blob: fa4d3db81bd7c576f75cd1977294e36ddf251f89 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11#include <stdio.h>
12
deadbeefcbecd352015-09-23 11:50:27 -070013#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
Steve Anton36b29d12017-10-30 09:57:42 -070015#include <utility>
deadbeefcbecd352015-09-23 11:50:27 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "pc/statscollector.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "pc/mediastream.h"
20#include "pc/mediastreamtrack.h"
Steve Anton3871f6f2018-01-26 10:25:53 -080021#include "pc/test/fakepeerconnectionforstats.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "pc/test/fakevideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "pc/videotrack.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/fakesslidentity.h"
Artem Titova76af0c2018-07-23 17:38:12 +020025#include "rtc_base/third_party/base64/base64.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
Steve Anton3871f6f2018-01-26 10:25:53 -080028using cricket::ConnectionInfo;
29using cricket::SsrcReceiverInfo;
30using cricket::TransportChannelStats;
31using cricket::VideoMediaInfo;
32using cricket::VideoReceiverInfo;
33using cricket::VideoSenderInfo;
34using cricket::VoiceMediaInfo;
35using cricket::VoiceReceiverInfo;
36using cricket::VoiceSenderInfo;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000038namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039
tkchin7d06a8c2016-04-04 14:10:43 -070040namespace internal {
41// This value comes from openssl/tls1.h
42static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
43} // namespace internal
44
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045// Error return values
46const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047
wu@webrtc.org97077a32013-10-25 21:18:33 +000048// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000049const char kLocalTrackId[] = "local_track_id";
50const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020051const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000052
Steve Anton3871f6f2018-01-26 10:25:53 -080053class FakeAudioProcessor : public AudioProcessorInterface {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000054 public:
55 FakeAudioProcessor() {}
56 ~FakeAudioProcessor() {}
57
58 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000059 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000060 stats->typing_noise_detected = true;
61 stats->echo_return_loss = 2;
62 stats->echo_return_loss_enhancement = 3;
63 stats->echo_delay_median_ms = 4;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000064 stats->echo_delay_std_ms = 6;
65 }
Ivo Creusenae026092017-11-20 13:07:16 +010066
67 AudioProcessorInterface::AudioProcessorStatistics GetStats(
Ivo Creusen56d46092017-11-24 17:29:59 +010068 bool has_recv_streams) override {
Ivo Creusenae026092017-11-20 13:07:16 +010069 AudioProcessorStatistics stats;
70 stats.typing_noise_detected = true;
Ivo Creusen56d46092017-11-24 17:29:59 +010071 if (has_recv_streams) {
72 stats.apm_statistics.echo_return_loss = 2.0;
73 stats.apm_statistics.echo_return_loss_enhancement = 3.0;
74 stats.apm_statistics.delay_median_ms = 4;
75 stats.apm_statistics.delay_standard_deviation_ms = 5;
76 }
Ivo Creusenae026092017-11-20 13:07:16 +010077 return stats;
78 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000079};
80
Steve Anton3871f6f2018-01-26 10:25:53 -080081class FakeAudioTrack : public MediaStreamTrack<AudioTrackInterface> {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000082 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +000083 explicit FakeAudioTrack(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -080084 : MediaStreamTrack<AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000085 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000086 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -080087 AudioSourceInterface* GetSource() const override { return NULL; }
88 void AddSink(AudioTrackSinkInterface* sink) override {}
89 void RemoveSink(AudioTrackSinkInterface* sink) override {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000090 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000091 *level = 1;
92 return true;
93 }
Steve Anton3871f6f2018-01-26 10:25:53 -080094 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000095 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000096 }
97
98 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000099 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000100};
101
zhihuang6ba3b192016-05-13 11:46:35 -0700102// This fake audio processor is used to verify that the undesired initial values
103// (-1) will be filtered out.
Steve Anton3871f6f2018-01-26 10:25:53 -0800104class FakeAudioProcessorWithInitValue : public AudioProcessorInterface {
zhihuang6ba3b192016-05-13 11:46:35 -0700105 public:
106 FakeAudioProcessorWithInitValue() {}
107 ~FakeAudioProcessorWithInitValue() {}
108
109 private:
110 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
111 stats->typing_noise_detected = false;
112 stats->echo_return_loss = -100;
113 stats->echo_return_loss_enhancement = -100;
114 stats->echo_delay_median_ms = -1;
zhihuang6ba3b192016-05-13 11:46:35 -0700115 stats->echo_delay_std_ms = -1;
116 }
Ivo Creusenae026092017-11-20 13:07:16 +0100117
118 AudioProcessorInterface::AudioProcessorStatistics GetStats(
119 bool /*has_recv_streams*/) override {
120 AudioProcessorStatistics stats;
121 stats.typing_noise_detected = false;
122 return stats;
123 }
zhihuang6ba3b192016-05-13 11:46:35 -0700124};
125
126class FakeAudioTrackWithInitValue
Steve Anton3871f6f2018-01-26 10:25:53 -0800127 : public MediaStreamTrack<AudioTrackInterface> {
zhihuang6ba3b192016-05-13 11:46:35 -0700128 public:
129 explicit FakeAudioTrackWithInitValue(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -0800130 : MediaStreamTrack<AudioTrackInterface>(id),
zhihuang6ba3b192016-05-13 11:46:35 -0700131 processor_(
132 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
133 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -0800134 AudioSourceInterface* GetSource() const override { return NULL; }
135 void AddSink(AudioTrackSinkInterface* sink) override {}
136 void RemoveSink(AudioTrackSinkInterface* sink) override {}
zhihuang6ba3b192016-05-13 11:46:35 -0700137 bool GetSignalLevel(int* level) override {
138 *level = 1;
139 return true;
140 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800141 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
zhihuang6ba3b192016-05-13 11:46:35 -0700142 return processor_;
143 }
144
145 private:
146 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
147};
148
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000149bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000150 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000151 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000152 const StatsReport::Value* v = report->FindValue(name);
153 if (!v)
154 return false;
155 *value = v->ToString();
156 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000157}
158
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000159std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000160 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000161 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000162 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000163 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000164 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000165 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
167
168 return kNotFound;
169}
170
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000171StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
172 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000173 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000174 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000175 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000176 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000177
178 // This has assumptions about how the ID is constructed. As is, this is
179 // OK since this is for testing purposes only, but if we ever need this
180 // in production, we should add a generic method that does this.
181 size_t index = value.find('_');
182 EXPECT_NE(index, std::string::npos);
183 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000184 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000185
186 id = StatsReport::NewTypedId(type, value.substr(index + 1));
187 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000188 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000189}
190
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000191StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
192 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000193}
194
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195// Finds the |n|-th report of type |type| in |reports|.
196// |n| starts from 1 for finding the first report.
Yves Gerey665174f2018-06-19 15:03:05 +0200197const StatsReport* FindNthReportByType(const StatsReports& reports,
198 const StatsReport::StatsType& type,
199 int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000201 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 n--;
203 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000204 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
206 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000207 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208}
209
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000210const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000211 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000212 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000213 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000214 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000216 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217}
218
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100219std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000220 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000221 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222}
223
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100224std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000225 StatsReport::StatsValueName name) {
Yves Gerey665174f2018-06-19 15:03:05 +0200226 return ExtractStatsValue(StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227}
228
wu@webrtc.org4551b792013-10-09 15:37:36 +0000229std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000230 return rtc::SSLIdentity::DerToPem(
Yves Gerey665174f2018-06-19 15:03:05 +0200231 rtc::kPemTypeCertificate,
232 reinterpret_cast<const unsigned char*>(der.c_str()), der.length());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000233}
234
Yves Gerey665174f2018-06-19 15:03:05 +0200235std::vector<std::string> DersToPems(const std::vector<std::string>& ders) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000236 std::vector<std::string> pems(ders.size());
237 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
238 return pems;
239}
240
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000241void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000242 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000243 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000244 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000245 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000246 size_t i = 0;
247 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000248 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000249 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000250
wu@webrtc.org4551b792013-10-09 15:37:36 +0000251 std::string der_base64;
Yves Gerey665174f2018-06-19 15:03:05 +0200252 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000253 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000254 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000255
256 std::string fingerprint_algorithm;
Yves Gerey665174f2018-06-19 15:03:05 +0200257 EXPECT_TRUE(GetValue(report,
258 StatsReport::kStatsValueNameFingerprintAlgorithm,
259 &fingerprint_algorithm));
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000260 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000261 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000262 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
263
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000264 std::string fingerprint;
265 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
266 &fingerprint));
267 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000268
wu@webrtc.org4551b792013-10-09 15:37:36 +0000269 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000270 std::string issuer_id;
Yves Gerey665174f2018-06-19 15:03:05 +0200271 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId, &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000272 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000273 }
274
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000275 cert_id = IdFromCertIdString(issuer_id);
276 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000277 }
278 EXPECT_EQ(ders.size(), i);
279}
280
Yves Gerey665174f2018-06-19 15:03:05 +0200281void VerifyVoiceReceiverInfoReport(const StatsReport* report,
282 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000283 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200284 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioOutputLevel,
285 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200286 EXPECT_EQ(rtc::ToString(info.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200287 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived,
288 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200289 EXPECT_EQ(rtc::ToString(info.bytes_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200290 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
291 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200292 EXPECT_EQ(rtc::ToString(info.jitter_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200293 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterBufferMs,
294 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200295 EXPECT_EQ(rtc::ToString(info.jitter_buffer_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200296 EXPECT_TRUE(GetValue(report,
297 StatsReport::kStatsValueNamePreferredJitterBufferMs,
298 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200299 EXPECT_EQ(rtc::ToString(info.jitter_buffer_preferred_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200300 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCurrentDelayMs,
301 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200302 EXPECT_EQ(rtc::ToString(info.delay_estimate_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200303 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameExpandRate,
304 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200305 EXPECT_EQ(rtc::ToString(info.expand_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200306 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSpeechExpandRate,
307 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200308 EXPECT_EQ(rtc::ToString(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200309 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
310 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200311 EXPECT_EQ(rtc::ToString(info.accelerate_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200312 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
313 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200314 EXPECT_EQ(rtc::ToString(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000315 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
316 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200317 EXPECT_EQ(rtc::ToString(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200318 EXPECT_TRUE(GetValue(report,
319 StatsReport::kStatsValueNameSecondaryDiscardedRate,
320 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200321 EXPECT_EQ(rtc::ToString(info.secondary_discarded_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200322 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived,
323 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200324 EXPECT_EQ(rtc::ToString(info.packets_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200325 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG,
326 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200327 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_silence_generator),
Yves Gerey665174f2018-06-19 15:03:05 +0200328 value_in_report);
329 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTN,
330 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200331 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_neteq), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200332 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingNormal,
333 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200334 EXPECT_EQ(rtc::ToString(info.decoding_normal), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200335 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
336 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200337 EXPECT_EQ(rtc::ToString(info.decoding_plc), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200338 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
339 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200340 EXPECT_EQ(rtc::ToString(info.decoding_cng), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200341 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLCCNG,
342 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200343 EXPECT_EQ(rtc::ToString(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700344 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
345 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200346 EXPECT_EQ(rtc::ToString(info.decoding_muted_output), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700347 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
348 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000349}
350
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000351void VerifyVoiceSenderInfoReport(const StatsReport* report,
352 const cricket::VoiceSenderInfo& sinfo) {
353 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200354 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
355 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000356 EXPECT_EQ(sinfo.codec_name, value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200357 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesSent,
358 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200359 EXPECT_EQ(rtc::ToString(sinfo.bytes_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200360 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsSent,
361 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200362 EXPECT_EQ(rtc::ToString(sinfo.packets_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200363 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
364 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200365 EXPECT_EQ(rtc::ToString(sinfo.packets_lost), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200366 EXPECT_TRUE(
367 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200368 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200369 EXPECT_TRUE(
370 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200371 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200372 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
373 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200374 EXPECT_EQ(rtc::ToString(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100375 if (sinfo.apm_statistics.delay_median_ms) {
376 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
377 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200378 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_median_ms),
Ivo Creusen56d46092017-11-24 17:29:59 +0100379 value_in_report);
380 } else {
381 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
382 &value_in_report));
383 }
384 if (sinfo.apm_statistics.delay_standard_deviation_ms) {
385 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
386 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200387 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_standard_deviation_ms),
388 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100389 } else {
390 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
391 &value_in_report));
392 }
393 if (sinfo.apm_statistics.echo_return_loss) {
394 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
395 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200396 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss),
Ivo Creusen56d46092017-11-24 17:29:59 +0100397 value_in_report);
398 } else {
399 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
400 &value_in_report));
401 }
402 if (sinfo.apm_statistics.echo_return_loss_enhancement) {
403 EXPECT_TRUE(GetValue(report,
404 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
405 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200406 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss_enhancement),
407 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100408 } else {
409 EXPECT_FALSE(GetValue(report,
410 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
411 &value_in_report));
412 }
413 if (sinfo.apm_statistics.residual_echo_likelihood) {
414 EXPECT_TRUE(GetValue(report,
415 StatsReport::kStatsValueNameResidualEchoLikelihood,
416 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200417 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.residual_echo_likelihood),
418 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100419 } else {
420 EXPECT_FALSE(GetValue(report,
421 StatsReport::kStatsValueNameResidualEchoLikelihood,
422 &value_in_report));
423 }
424 if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) {
425 EXPECT_TRUE(GetValue(
426 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
427 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200428 EXPECT_EQ(rtc::ToString(
Ivo Creusen56d46092017-11-24 17:29:59 +0100429 *sinfo.apm_statistics.residual_echo_likelihood_recent_max),
430 value_in_report);
431 } else {
432 EXPECT_FALSE(GetValue(
433 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
434 &value_in_report));
435 }
ivoc8c63a822016-10-21 04:10:03 -0700436 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
437 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200438 EXPECT_EQ(rtc::ToString(sinfo.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200439 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameTypingNoiseState,
440 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000441 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
442 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700443 EXPECT_TRUE(GetValue(report,
444 StatsReport::kStatsValueNameAnaBitrateActionCounter,
445 &value_in_report));
446 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200447 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.bitrate_action_counter),
448 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700449 EXPECT_TRUE(GetValue(report,
450 StatsReport::kStatsValueNameAnaChannelActionCounter,
451 &value_in_report));
452 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200453 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.channel_action_counter),
454 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700455 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
456 &value_in_report));
457 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200458 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.dtx_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700459 value_in_report);
460 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter,
461 &value_in_report));
462 ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200463 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.fec_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700464 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700465 EXPECT_TRUE(GetValue(
466 report, StatsReport::kStatsValueNameAnaFrameLengthIncreaseCounter,
467 &value_in_report));
468 ASSERT_TRUE(sinfo.ana_statistics.frame_length_increase_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200469 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 08:13:19 -0700470 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700471 EXPECT_TRUE(GetValue(
472 report, StatsReport::kStatsValueNameAnaFrameLengthDecreaseCounter,
473 &value_in_report));
474 ASSERT_TRUE(sinfo.ana_statistics.frame_length_decrease_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200475 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_decrease_counter),
ivoc0d0b9122017-09-08 13:24:21 -0700476 value_in_report);
477 EXPECT_TRUE(GetValue(report,
478 StatsReport::kStatsValueNameAnaUplinkPacketLossFraction,
479 &value_in_report));
480 ASSERT_TRUE(sinfo.ana_statistics.uplink_packet_loss_fraction);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200481 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.uplink_packet_loss_fraction),
482 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000483}
484
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000485// Helper methods to avoid duplication of code.
486void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
487 voice_sender_info->add_ssrc(kSsrcOfTrack);
488 voice_sender_info->codec_name = "fake_codec";
489 voice_sender_info->bytes_sent = 100;
490 voice_sender_info->packets_sent = 101;
491 voice_sender_info->rtt_ms = 102;
492 voice_sender_info->fraction_lost = 103;
493 voice_sender_info->jitter_ms = 104;
494 voice_sender_info->packets_lost = 105;
495 voice_sender_info->ext_seqnum = 106;
496 voice_sender_info->audio_level = 107;
497 voice_sender_info->echo_return_loss = 108;
498 voice_sender_info->echo_return_loss_enhancement = 109;
499 voice_sender_info->echo_delay_median_ms = 110;
500 voice_sender_info->echo_delay_std_ms = 111;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000501 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d46092017-11-24 17:29:59 +0100502 voice_sender_info->ana_statistics.bitrate_action_counter = 112;
503 voice_sender_info->ana_statistics.channel_action_counter = 113;
504 voice_sender_info->ana_statistics.dtx_action_counter = 114;
505 voice_sender_info->ana_statistics.fec_action_counter = 115;
506 voice_sender_info->ana_statistics.frame_length_increase_counter = 116;
507 voice_sender_info->ana_statistics.frame_length_decrease_counter = 117;
508 voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000509}
510
511void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700512 AudioTrackInterface* audio_track,
Ivo Creusen56d46092017-11-24 17:29:59 +0100513 cricket::VoiceSenderInfo* voice_sender_info,
514 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000515 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 10:25:53 -0800516 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
517 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000518 voice_sender_info->typing_noise_detected =
519 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d46092017-11-24 17:29:59 +0100520 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000521}
522
523void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
524 voice_receiver_info->add_ssrc(kSsrcOfTrack);
525 voice_receiver_info->bytes_rcvd = 110;
526 voice_receiver_info->packets_rcvd = 111;
527 voice_receiver_info->packets_lost = 112;
528 voice_receiver_info->fraction_lost = 113;
529 voice_receiver_info->packets_lost = 114;
530 voice_receiver_info->ext_seqnum = 115;
531 voice_receiver_info->jitter_ms = 116;
532 voice_receiver_info->jitter_buffer_ms = 117;
533 voice_receiver_info->jitter_buffer_preferred_ms = 118;
534 voice_receiver_info->delay_estimate_ms = 119;
535 voice_receiver_info->audio_level = 120;
536 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000537 voice_receiver_info->speech_expand_rate = 122;
538 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200539 voice_receiver_info->accelerate_rate = 124;
540 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200541 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000542}
543
Steve Anton3871f6f2018-01-26 10:25:53 -0800544class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000545 public:
Steve Anton3871f6f2018-01-26 10:25:53 -0800546 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 11:33:11 -0700547 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000548
Yves Gerey665174f2018-06-19 15:03:05 +0200549 double GetTimeNow() override { return time_now_; }
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000550
551 private:
552 double time_now_;
553};
554
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555class StatsCollectorTest : public testing::Test {
556 protected:
Steve Anton3871f6f2018-01-26 10:25:53 -0800557 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
558 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 }
560
Steve Anton3871f6f2018-01-26 10:25:53 -0800561 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
562 PeerConnectionInternal* pc) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200563 return absl::make_unique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000564 }
565
Steve Anton3871f6f2018-01-26 10:25:53 -0800566 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
567 StatsCollectorForTest* stats,
568 const VoiceMediaInfo& voice_info,
569 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38 +0000570 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000571 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 10:25:53 -0800572 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000573
574 // Verify the existence of the track report.
Yves Gerey665174f2018-06-19 15:03:05 +0200575 const StatsReport* report =
576 FindNthReportByType(*reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800577 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 15:06:43 -0700578 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +0200579 std::string track_id =
580 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000581 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200582 std::string ssrc_id =
583 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200584 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000585
Yves Gerey665174f2018-06-19 15:03:05 +0200586 std::string media_type =
587 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -0800588 EXPECT_EQ("audio", media_type);
589
xians@webrtc.org01bda202014-07-09 07:38:38 +0000590 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 10:25:53 -0800591 if (!voice_info.senders.empty()) {
592 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000593 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800594 if (!voice_info.receivers.empty()) {
595 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000596 }
597
598 // Verify we get the same result by passing a track to GetStats().
599 StatsReports track_reports; // returned values.
600 stats->GetStats(audio_track, &track_reports);
601 const StatsReport* track_report = FindNthReportByType(
602 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800603 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700604 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000605 track_id = ExtractSsrcStatsValue(track_reports,
606 StatsReport::kStatsValueNameTrackId);
607 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200608 ssrc_id =
609 ExtractSsrcStatsValue(track_reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200610 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 10:25:53 -0800611 if (!voice_info.senders.empty()) {
612 VerifyVoiceSenderInfoReport(track_report, voice_info.senders[0]);
613 }
614 if (!voice_info.receivers.empty()) {
615 VerifyVoiceReceiverInfoReport(track_report, voice_info.receivers[0]);
616 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000617 }
618
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800619 void TestCertificateReports(const rtc::FakeSSLIdentity& local_identity,
620 const std::vector<std::string>& local_ders,
621 const rtc::FakeSSLIdentity& remote_identity,
622 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800623 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000624
Steve Anton3871f6f2018-01-26 10:25:53 -0800625 auto pc = CreatePeerConnection();
626 auto stats = CreateStatsCollector(pc);
627
Steve Anton5b387312018-02-02 16:00:20 -0800628 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000629
630 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800631 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000632 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800633 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700634 channel_stats.ssl_cipher_suite =
635 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800636 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000637
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800638 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 10:12:24 +0200639 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800640 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800641 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 10:25:53 -0800642 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800643 pc->SetRemoteCertChain(kTransportName,
644 remote_identity.cert_chain().UniqueCopy());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000645
Steve Anton3871f6f2018-01-26 10:25:53 -0800646 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000647
Steve Anton3871f6f2018-01-26 10:25:53 -0800648 StatsReports reports;
649 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000650
Yves Gerey665174f2018-06-19 15:03:05 +0200651 const StatsReport* channel_report =
652 FindNthReportByType(reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800653 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000654
655 // Check local certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200656 std::string local_certificate_id =
657 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
658 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000659 if (local_ders.size() > 0) {
660 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000661 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
662 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000663 } else {
664 EXPECT_EQ(kNotFound, local_certificate_id);
665 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000666
667 // Check remote certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200668 std::string remote_certificate_id =
669 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
670 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000671 if (remote_ders.size() > 0) {
672 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000673 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
674 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000675 } else {
676 EXPECT_EQ(kNotFound, remote_certificate_id);
677 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000678
679 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800680 std::string dtls_cipher_suite =
681 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
682 StatsReport::kStatsValueNameDtlsCipher);
683 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700684 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800685 dtls_cipher_suite);
686 std::string srtp_crypto_suite =
687 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
688 StatsReport::kStatsValueNameSrtpCipher);
689 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
690 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000691 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100692};
693
694class StatsCollectorTrackTest : public StatsCollectorTest,
695 public ::testing::WithParamInterface<bool> {
696 public:
697 // Adds a outgoing video track with a given SSRC into the stats.
698 // If GetParam() returns true, the track is also inserted into the local
699 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800700 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
701 StatsCollectorForTest* stats) {
702 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
703 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100704 if (GetParam()) {
705 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800706 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100707 stream_->AddTrack(track_);
708 stats->AddStream(stream_);
709 } else {
710 stats->AddTrack(track_);
711 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800712 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100713 }
714
715 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800716 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
717 StatsCollectorForTest* stats) {
718 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
719 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100720 if (GetParam()) {
Seth Hampson845e8782018-03-02 11:34:10 -0800721 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100722 stream_->AddTrack(track_);
723 stats->AddStream(stream_);
724 } else {
725 stats->AddTrack(track_);
726 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800727 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100728 }
729
730 // Adds a outgoing audio track with a given SSRC into the stats,
731 // and register it into the stats object.
732 // If GetParam() returns true, the track is also inserted into the local
733 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800734 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
735 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100736 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
737 if (GetParam()) {
738 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800739 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100740 stream_->AddTrack(audio_track_);
741 stats->AddStream(stream_);
742 } else {
743 stats->AddTrack(audio_track_);
744 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800745 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100746 }
747
748 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800749 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
750 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100751 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
752 if (GetParam()) {
753 if (stream_ == NULL)
Seth Hampson845e8782018-03-02 11:34:10 -0800754 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100755 stream_->AddTrack(audio_track_);
756 stats->AddStream(stream_);
757 } else {
758 stats->AddTrack(audio_track_);
759 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800760 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100761 }
762
Steve Anton3871f6f2018-01-26 10:25:53 -0800763 rtc::scoped_refptr<MediaStream> stream_;
764 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000765 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766};
767
zhihuang6ba3b192016-05-13 11:46:35 -0700768TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800769 auto pc = CreatePeerConnection();
770 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -0700771
Steve Anton3871f6f2018-01-26 10:25:53 -0800772 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 11:46:35 -0700773
Steve Anton3871f6f2018-01-26 10:25:53 -0800774 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -0700775 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800776 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 11:46:35 -0700777
778 const StatsReport* report =
779 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
780
781 std::string value_in_report;
782 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
783 &value_in_report));
784}
785
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000786// Verify that ExtractDataInfo populates reports.
787TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800788 const std::string kDataChannelLabel = "hacks";
789 constexpr int kDataChannelId = 31337;
790 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000791 DataChannelInterface::DataState::kConnecting);
792
Steve Anton3871f6f2018-01-26 10:25:53 -0800793 auto pc = CreatePeerConnection();
794 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000795
Steve Anton3871f6f2018-01-26 10:25:53 -0800796 InternalDataChannelInit init;
797 init.id = kDataChannelId;
798 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000799
Steve Anton3871f6f2018-01-26 10:25:53 -0800800 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000801 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800802 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000803
804 const StatsReport* report =
805 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
806
Steve Anton3871f6f2018-01-26 10:25:53 -0800807 StatsReport::Id report_id = StatsReport::NewTypedIntId(
808 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000809
Steve Anton3871f6f2018-01-26 10:25:53 -0800810 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000811
Steve Anton3871f6f2018-01-26 10:25:53 -0800812 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
813 EXPECT_EQ(kDataChannelLabel,
814 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
815 StatsReport::kStatsValueNameLabel));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200816 EXPECT_EQ(rtc::ToString(kDataChannelId),
Peter Boström0c4e06b2015-10-07 12:23:21 +0200817 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000818 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 10:25:53 -0800819 EXPECT_EQ(kConnectingString,
820 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
821 StatsReport::kStatsValueNameState));
Yves Gerey665174f2018-06-19 15:03:05 +0200822 EXPECT_EQ("",
823 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
824 StatsReport::kStatsValueNameProtocol));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000825}
826
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100828TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 10:25:53 -0800830 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000831
Steve Anton3871f6f2018-01-26 10:25:53 -0800832 auto pc = CreatePeerConnection();
833 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834
Steve Anton3871f6f2018-01-26 10:25:53 -0800835 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000836 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800838 VideoMediaInfo video_info;
839 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800840
841 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
842 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843
Steve Anton3871f6f2018-01-26 10:25:53 -0800844 AddOutgoingVideoTrack(pc, stats.get());
845
846 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
847 StatsReports reports;
848 stats->GetStats(nullptr, &reports);
849
850 EXPECT_EQ(
851 rtc::ToString(kBytesSent),
852 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853}
854
Alex Narest42308f62017-06-19 17:58:12 +0200855// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100856TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 17:58:12 +0200857 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
858 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800859 constexpr int64_t kBytesSent = 12345678901234LL;
860 constexpr int kSendBandwidth = 1234567;
861 constexpr int kRecvBandwidth = 12345678;
862 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 17:58:12 +0200863
Steve Anton3871f6f2018-01-26 10:25:53 -0800864 auto pc = CreatePeerConnection();
865 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 17:58:12 +0200866
Steve Anton3871f6f2018-01-26 10:25:53 -0800867 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 17:58:12 +0200868 voice_sender_info.add_ssrc(1234);
869 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800870 VoiceMediaInfo voice_info;
871 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800872
873 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
874 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 17:58:12 +0200875
Steve Anton3871f6f2018-01-26 10:25:53 -0800876 AddOutgoingAudioTrack(pc, stats.get());
877
878 Call::Stats call_stats;
Alex Narest42308f62017-06-19 17:58:12 +0200879 call_stats.send_bandwidth_bps = kSendBandwidth;
880 call_stats.recv_bandwidth_bps = kRecvBandwidth;
881 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800882 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 17:58:12 +0200883
Steve Anton3871f6f2018-01-26 10:25:53 -0800884 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
885 StatsReports reports;
886 stats->GetStats(nullptr, &reports);
887
888 EXPECT_EQ(
889 rtc::ToString(kBytesSent),
890 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
891 EXPECT_EQ(rtc::ToString(kSendBandwidth),
892 ExtractBweStatsValue(
893 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
894 EXPECT_EQ(
895 rtc::ToString(kRecvBandwidth),
896 ExtractBweStatsValue(
897 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
898 EXPECT_EQ(
899 rtc::ToString(kPacerDelay),
900 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
Alex Narest42308f62017-06-19 17:58:12 +0200901}
902
903// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100904TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
906 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800907 constexpr int64_t kBytesSent = 12345678901234LL;
908 constexpr int kSendBandwidth = 1234567;
909 constexpr int kRecvBandwidth = 12345678;
910 constexpr int kPacerDelay = 123;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000911
Steve Anton3871f6f2018-01-26 10:25:53 -0800912 auto pc = CreatePeerConnection();
913 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914
Steve Anton3871f6f2018-01-26 10:25:53 -0800915 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000916 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800918 VideoMediaInfo video_info;
919 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800920
921 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
922 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923
Steve Anton3871f6f2018-01-26 10:25:53 -0800924 AddOutgoingVideoTrack(pc, stats.get());
925
926 Call::Stats call_stats;
stefanf79ade12017-06-02 06:44:03 -0700927 call_stats.send_bandwidth_bps = kSendBandwidth;
928 call_stats.recv_bandwidth_bps = kRecvBandwidth;
929 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800930 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000931
Steve Anton3871f6f2018-01-26 10:25:53 -0800932 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
933 StatsReports reports;
934 stats->GetStats(nullptr, &reports);
935
936 EXPECT_EQ(
937 rtc::ToString(kBytesSent),
938 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
939 EXPECT_EQ(rtc::ToString(kSendBandwidth),
940 ExtractBweStatsValue(
941 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
942 EXPECT_EQ(
943 rtc::ToString(kRecvBandwidth),
944 ExtractBweStatsValue(
945 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
946 EXPECT_EQ(
947 rtc::ToString(kPacerDelay),
948 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000949}
950
951// This test verifies that an object of type "googSession" always
952// exists in the returned stats.
953TEST_F(StatsCollectorTest, SessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800954 auto pc = CreatePeerConnection();
955 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000956
Steve Anton3871f6f2018-01-26 10:25:53 -0800957 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
958 StatsReports reports;
959 stats->GetStats(nullptr, &reports);
960
961 EXPECT_TRUE(
962 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
965// This test verifies that only one object of type "googSession" exists
966// in the returned stats.
967TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800968 auto pc = CreatePeerConnection();
969 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000970
Steve Anton3871f6f2018-01-26 10:25:53 -0800971 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
972 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
973 StatsReports reports;
974 stats->GetStats(nullptr, &reports);
975
976 EXPECT_TRUE(
977 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
978 EXPECT_FALSE(
979 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980}
981
982// This test verifies that the empty track report exists in the returned stats
983// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100984TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800985 auto pc = CreatePeerConnection();
986 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000987
Steve Anton5b387312018-02-02 16:00:20 -0800988 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -0800989 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000990
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000992 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800993 stats->GetStats(nullptr, &reports);
994 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000995 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -0700996 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000997
998 std::string trackValue =
Yves Gerey665174f2018-06-19 15:03:05 +0200999 ExtractStatsValue(StatsReport::kStatsReportTypeTrack, reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001000 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001001 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002}
1003
1004// This test verifies that the empty track report exists in the returned stats
1005// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001006TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001007 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001008
Steve Anton3871f6f2018-01-26 10:25:53 -08001009 auto pc = CreatePeerConnection();
1010 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001011
Steve Anton3871f6f2018-01-26 10:25:53 -08001012 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001013 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001015 VideoMediaInfo video_info;
1016 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001017
1018 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1019 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020
Steve Anton3871f6f2018-01-26 10:25:53 -08001021 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022
Steve Anton3871f6f2018-01-26 10:25:53 -08001023 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001024 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001025 stats->GetStats(nullptr, &reports);
1026
wu@webrtc.org97077a32013-10-25 21:18:33 +00001027 // |reports| should contain at least one session report, one track report,
1028 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001029 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001030 const StatsReport* track_report =
1031 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001032 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001033
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001034 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001035 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001036 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001037 // |reports| should contain at least one session report, one track report,
1038 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001039 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001040 track_report =
1041 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001042 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001043 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044
Yves Gerey665174f2018-06-19 15:03:05 +02001045 std::string ssrc_id =
1046 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001047 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001048
Yves Gerey665174f2018-06-19 15:03:05 +02001049 std::string track_id =
1050 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001051 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001052
Yves Gerey665174f2018-06-19 15:03:05 +02001053 std::string media_type =
1054 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -08001055 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001056}
1057
1058// This test verifies that an SSRC object has the identifier of a Transport
1059// stats object, and that this transport stats object exists in stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001060TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001061 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001062
Steve Anton3871f6f2018-01-26 10:25:53 -08001063 auto pc = CreatePeerConnection();
1064 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001065
Steve Anton3871f6f2018-01-26 10:25:53 -08001066 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001067 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001069 VideoMediaInfo video_info;
1070 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001071
1072 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1073 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074
Steve Anton3871f6f2018-01-26 10:25:53 -08001075 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001076
Steve Anton3871f6f2018-01-26 10:25:53 -08001077 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001078 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001079 stats->GetStats(nullptr, &reports);
1080
Yves Gerey665174f2018-06-19 15:03:05 +02001081 std::string transport_id =
1082 ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports,
1083 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001084 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001085
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001086 // Transport id component ID will always be 1.
1087 // This has assumptions about how the ID is constructed. As is, this is
1088 // OK since this is for testing purposes only, but if we ever need this
1089 // in production, we should add a generic method that does this.
1090 size_t index = transport_id.find('-');
1091 ASSERT_NE(std::string::npos, index);
1092 std::string content = transport_id.substr(index + 1);
1093 index = content.rfind('-');
1094 ASSERT_NE(std::string::npos, index);
1095 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001096 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001097 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001098 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001099 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001100}
1101
wu@webrtc.org97077a32013-10-25 21:18:33 +00001102// This test verifies that a remote stats object will not be created for
1103// an outgoing SSRC where remote stats are not returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001104TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001105 auto pc = CreatePeerConnection();
1106 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001107
Steve Anton5b387312018-02-02 16:00:20 -08001108 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001109 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001110
Steve Anton3871f6f2018-01-26 10:25:53 -08001111 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001112 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001113 stats->GetStats(nullptr, &reports);
1114
Yves Gerey665174f2018-06-19 15:03:05 +02001115 const StatsReport* remote_report =
1116 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001117 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001118}
1119
1120// This test verifies that a remote stats object will be created for
1121// an outgoing SSRC where stats are returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001122TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001123 auto pc = CreatePeerConnection();
1124 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001125
Steve Anton3871f6f2018-01-26 10:25:53 -08001126 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001127 remote_ssrc_stats.timestamp = 12345.678;
1128 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 10:25:53 -08001129 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001130 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001131 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 10:25:53 -08001132 VideoMediaInfo video_info;
1133 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001134
1135 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1136 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001137
Steve Anton3871f6f2018-01-26 10:25:53 -08001138 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001139
Steve Anton3871f6f2018-01-26 10:25:53 -08001140 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001141 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001142 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001143
Yves Gerey665174f2018-06-19 15:03:05 +02001144 const StatsReport* remote_report =
1145 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001146 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001147 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001148}
1149
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001150// This test verifies that the empty track report exists in the returned stats
1151// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001152TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001153 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001154
Steve Anton3871f6f2018-01-26 10:25:53 -08001155 auto pc = CreatePeerConnection();
1156 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001157
Steve Anton3871f6f2018-01-26 10:25:53 -08001158 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001159 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001160 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 10:25:53 -08001161 VideoMediaInfo video_info;
1162 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001163
1164 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1165 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001166
Steve Anton3871f6f2018-01-26 10:25:53 -08001167 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001168
Steve Anton3871f6f2018-01-26 10:25:53 -08001169 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001170 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001171 stats->GetStats(nullptr, &reports);
1172
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001173 // |reports| should contain at least one session report, one track report,
1174 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001175 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001176 const StatsReport* track_report =
1177 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001178 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001179 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001180
Yves Gerey665174f2018-06-19 15:03:05 +02001181 std::string ssrc_id =
1182 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001183 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001184
Yves Gerey665174f2018-06-19 15:03:05 +02001185 std::string track_id =
1186 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001187 EXPECT_EQ(kRemoteTrackId, track_id);
1188}
1189
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001190// This test verifies the Ice Candidate report should contain the correct
1191// information from local/remote candidates.
1192TEST_F(StatsCollectorTest, IceCandidateReport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001193 const std::string kTransportName = "transport";
1194 const rtc::AdapterType kNetworkType = rtc::ADAPTER_TYPE_ETHERNET;
1195 constexpr uint32_t kPriority = 1000;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001196
Steve Anton3871f6f2018-01-26 10:25:53 -08001197 constexpr int kLocalPort = 2000;
1198 const std::string kLocalIp = "192.168.0.1";
1199 const rtc::SocketAddress kLocalAddress(kLocalIp, kLocalPort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001200
Steve Anton3871f6f2018-01-26 10:25:53 -08001201 constexpr int kRemotePort = 2001;
1202 const std::string kRemoteIp = "192.168.0.2";
1203 const rtc::SocketAddress kRemoteAddress(kRemoteIp, kRemotePort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001204
Steve Anton3871f6f2018-01-26 10:25:53 -08001205 auto pc = CreatePeerConnection();
1206 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001207
Steve Anton3871f6f2018-01-26 10:25:53 -08001208 cricket::Candidate local;
1209 EXPECT_GT(local.id().length(), 0u);
1210 local.set_type(cricket::LOCAL_PORT_TYPE);
1211 local.set_protocol(cricket::UDP_PROTOCOL_NAME);
1212 local.set_address(kLocalAddress);
1213 local.set_priority(kPriority);
1214 local.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001215
Steve Anton3871f6f2018-01-26 10:25:53 -08001216 cricket::Candidate remote;
1217 EXPECT_GT(remote.id().length(), 0u);
1218 remote.set_type(cricket::PRFLX_PORT_TYPE);
1219 remote.set_protocol(cricket::UDP_PROTOCOL_NAME);
1220 remote.set_address(kRemoteAddress);
1221 remote.set_priority(kPriority);
1222 remote.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001223
Steve Anton3871f6f2018-01-26 10:25:53 -08001224 ConnectionInfo connection_info;
1225 connection_info.local_candidate = local;
1226 connection_info.remote_candidate = remote;
1227 TransportChannelStats channel_stats;
1228 channel_stats.connection_infos.push_back(connection_info);
1229
Steve Anton5b387312018-02-02 16:00:20 -08001230 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 10:25:53 -08001231 pc->SetTransportStats(kTransportName, channel_stats);
1232
1233 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1234 StatsReports reports;
1235 stats->GetStats(nullptr, &reports);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001236
1237 // Verify the local candidate report is populated correctly.
1238 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001239 "Cand-" + local.id(),
1240 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1241 StatsReport::kStatsValueNameLocalCandidateId));
1242 EXPECT_EQ(
1243 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001244 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1245 StatsReport::kStatsValueNameCandidateIPAddress));
1246 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001247 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001248 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1249 StatsReport::kStatsValueNameCandidatePortNumber));
1250 EXPECT_EQ(
1251 cricket::UDP_PROTOCOL_NAME,
1252 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1253 StatsReport::kStatsValueNameCandidateTransportType));
1254 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001255 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001256 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1257 StatsReport::kStatsValueNameCandidatePriority));
1258 EXPECT_EQ(
1259 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1260 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1261 StatsReport::kStatsValueNameCandidateType));
1262 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001263 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001264 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1265 StatsReport::kStatsValueNameCandidateNetworkType));
1266
1267 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 10:25:53 -08001268 EXPECT_EQ(
1269 "Cand-" + remote.id(),
1270 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1271 StatsReport::kStatsValueNameRemoteCandidateId));
1272 EXPECT_EQ(kRemoteIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001273 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1274 reports,
1275 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 10:25:53 -08001276 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001277 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1278 reports,
1279 StatsReport::kStatsValueNameCandidatePortNumber));
1280 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1281 ExtractStatsValue(
1282 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1283 StatsReport::kStatsValueNameCandidateTransportType));
Steve Anton3871f6f2018-01-26 10:25:53 -08001284 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001285 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1286 reports,
1287 StatsReport::kStatsValueNameCandidatePriority));
1288 EXPECT_EQ(
1289 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1290 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1291 reports, StatsReport::kStatsValueNameCandidateType));
1292 EXPECT_EQ(kNotFound,
1293 ExtractStatsValue(
1294 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1295 StatsReport::kStatsValueNameCandidateNetworkType));
1296}
1297
wu@webrtc.org4551b792013-10-09 15:37:36 +00001298// This test verifies that all chained certificates are correctly
1299// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001300TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001301 // Build local certificate chain.
1302 std::vector<std::string> local_ders(5);
1303 local_ders[0] = "These";
1304 local_ders[1] = "are";
1305 local_ders[2] = "some";
1306 local_ders[3] = "der";
1307 local_ders[4] = "values";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001308 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001309
1310 // Build remote certificate chain
1311 std::vector<std::string> remote_ders(4);
1312 remote_ders[0] = "A";
1313 remote_ders[1] = "non-";
1314 remote_ders[2] = "intersecting";
1315 remote_ders[3] = "set";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001316 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001317
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001318 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001319 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001320}
1321
1322// This test verifies that all certificates without chains are correctly
1323// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001324TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001325 // Build local certificate.
1326 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001327 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001328
1329 // Build remote certificate.
1330 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001331 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001332
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001333 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1334 remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001335 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001336}
1337
1338// This test verifies that the stats are generated correctly when no
1339// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001340TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001341 auto pc = CreatePeerConnection();
1342 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001343
Steve Anton3871f6f2018-01-26 10:25:53 -08001344 // This will cause the fake PeerConnection to generate a TransportStats entry
1345 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001346 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001347
Steve Anton3871f6f2018-01-26 10:25:53 -08001348 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1349 StatsReports reports;
1350 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001351
1352 // Check that the local certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001353 std::string local_certificate_id =
1354 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1355 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001356 ASSERT_EQ(kNotFound, local_certificate_id);
1357
1358 // Check that the remote certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001359 std::string remote_certificate_id =
1360 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1361 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001362 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001363
1364 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001365 std::string dtls_cipher_suite =
1366 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1367 StatsReport::kStatsValueNameDtlsCipher);
1368 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1369 std::string srtp_crypto_suite =
1370 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1371 StatsReport::kStatsValueNameSrtpCipher);
1372 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001373}
1374
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001375// This test verifies that a remote certificate with an unsupported digest
1376// algorithm is correctly ignored.
1377TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1378 // Build a local certificate.
1379 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001380 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001381
1382 // Build a remote certificate with an unsupported digest algorithm.
1383 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001384 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
1385 remote_cert.set_digest_algorithm("foobar");
1386 rtc::FakeSSLIdentity remote_identity(remote_cert);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001387
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001388 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1389 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001390}
1391
zhihuang6ba3b192016-05-13 11:46:35 -07001392// This test verifies that the audio/video related stats which are -1 initially
1393// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001394TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001395 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001396 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001397 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001398 }
zhihuang6ba3b192016-05-13 11:46:35 -07001399
Steve Anton3871f6f2018-01-26 10:25:53 -08001400 auto pc = CreatePeerConnection();
1401 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001402
1403 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 11:34:10 -08001404 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 11:46:35 -07001405 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1406 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1407 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001408 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001409 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001410 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001411 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001412 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001413
1414 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001415 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001416 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 11:46:35 -07001417 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1418 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001419 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001420 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001421 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001422 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001423 }
zhihuang6ba3b192016-05-13 11:46:35 -07001424
Steve Anton3871f6f2018-01-26 10:25:53 -08001425 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001426 voice_sender_info.add_ssrc(kSsrcOfTrack);
1427 // These values are set to -1 initially in audio_send_stream.
1428 // The voice_sender_info will read the values from audio_send_stream.
1429 voice_sender_info.rtt_ms = -1;
1430 voice_sender_info.packets_lost = -1;
1431 voice_sender_info.jitter_ms = -1;
1432
1433 // Some of the contents in |voice_sender_info| needs to be updated from the
1434 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001435 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1436 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001437
Steve Anton3871f6f2018-01-26 10:25:53 -08001438 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001439 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1440 voice_receiver_info.capture_start_ntp_time_ms = -1;
1441 voice_receiver_info.audio_level = -1;
1442
1443 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001444 VoiceMediaInfo voice_info;
1445 voice_info.senders.push_back(voice_sender_info);
1446 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001447
Steve Anton5b387312018-02-02 16:00:20 -08001448 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1449 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001450
Steve Anton3871f6f2018-01-26 10:25:53 -08001451 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001452
1453 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001454 StatsReports reports;
1455 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001456 const StatsReport* report =
1457 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001458 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001459 // The -1 will not be added to the stats report.
1460 std::string value_in_report;
1461 EXPECT_FALSE(
1462 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1463 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1464 &value_in_report));
1465 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1466 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001467 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1468 &value_in_report));
1469 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1470 &value_in_report));
1471
1472 // Get stats for the remote track.
1473 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001474 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001475 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001476 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001477 EXPECT_FALSE(GetValue(report,
1478 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1479 &value_in_report));
1480 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1481 &value_in_report));
1482}
1483
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001484// This test verifies that a local stats object can get statistics via
1485// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001486TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001487 auto pc = CreatePeerConnection();
1488 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001489
Steve Anton3871f6f2018-01-26 10:25:53 -08001490 AddOutgoingAudioTrack(pc, stats.get());
1491 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001492
Steve Anton3871f6f2018-01-26 10:25:53 -08001493 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001494 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001495 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1496 VoiceMediaInfo voice_info;
1497 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001498
1499 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1500 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001501
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001502 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001503 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001504
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001505 // Verify that there is no remote report for the local audio track because
1506 // we did not set it up.
Yves Gerey665174f2018-06-19 15:03:05 +02001507 const StatsReport* remote_report =
1508 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001509 EXPECT_TRUE(remote_report == NULL);
1510}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001511
1512// This test verifies that audio receive streams populate stats reports
1513// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001514TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001515 auto pc = CreatePeerConnection();
1516 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001517
Steve Anton3871f6f2018-01-26 10:25:53 -08001518 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001519
Steve Anton3871f6f2018-01-26 10:25:53 -08001520 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001521 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001522 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001523 VoiceMediaInfo voice_info;
1524 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001525
1526 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1527 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001528
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001529 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001530 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001531}
1532
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001533// This test verifies that a local stats object won't update its statistics
1534// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001535TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001536 auto pc = CreatePeerConnection();
1537 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001538
Steve Anton3871f6f2018-01-26 10:25:53 -08001539 AddOutgoingAudioTrack(pc, stats.get());
1540 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001541
Steve Anton3871f6f2018-01-26 10:25:53 -08001542 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001543 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001544 VoiceMediaInfo voice_info;
1545 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001546
Steve Anton5b387312018-02-02 16:00:20 -08001547 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1548 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001549
Steve Anton3871f6f2018-01-26 10:25:53 -08001550 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001551
Steve Anton3871f6f2018-01-26 10:25:53 -08001552 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1553 StatsReports reports;
1554 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001555
1556 // The report will exist since we don't remove them in RemoveStream().
Yves Gerey665174f2018-06-19 15:03:05 +02001557 const StatsReport* report =
1558 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001559 ASSERT_TRUE(report);
1560 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001561 std::string track_id =
1562 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001563 EXPECT_EQ(kLocalTrackId, track_id);
Yves Gerey665174f2018-06-19 15:03:05 +02001564 std::string ssrc_id =
1565 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001566 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001567
1568 // Verifies the values in the track report, no value will be changed by the
1569 // AudioTrackInterface::GetSignalValue() and
1570 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1571 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1572}
1573
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001574// This test verifies that when ongoing and incoming audio tracks are using
1575// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001576TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001577 auto pc = CreatePeerConnection();
1578 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001579
1580 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001581 AddOutgoingAudioTrack(pc, stats.get());
1582 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001583
1584 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001585 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001586 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001587 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1588 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001589 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001590 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001591 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001592
Steve Anton3871f6f2018-01-26 10:25:53 -08001593 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001594 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001595 // Some of the contents in |voice_sender_info| needs to be updated from the
1596 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001597 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1598 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001599
Steve Anton3871f6f2018-01-26 10:25:53 -08001600 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001601 InitVoiceReceiverInfo(&voice_receiver_info);
1602
1603 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001604 VoiceMediaInfo voice_info;
1605 voice_info.senders.push_back(voice_sender_info);
1606 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001607
Steve Anton3871f6f2018-01-26 10:25:53 -08001608 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001609 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1610 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001611
Steve Anton3871f6f2018-01-26 10:25:53 -08001612 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001613
1614 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001615 StatsReports reports; // returned values.
1616 stats->GetStats(audio_track_.get(), &reports);
1617
Yves Gerey665174f2018-06-19 15:03:05 +02001618 const StatsReport* track_report =
1619 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001620 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001621 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001622 std::string track_id =
1623 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001624 EXPECT_EQ(kLocalTrackId, track_id);
1625 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1626
1627 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001628 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001629 stats->GetStats(remote_track.get(), &reports);
Yves Gerey665174f2018-06-19 15:03:05 +02001630 track_report =
1631 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001632 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001633 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001634 track_id =
1635 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001636 EXPECT_EQ(kRemoteTrackId, track_id);
1637 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1638}
1639
xians@webrtc.org01bda202014-07-09 07:38:38 +00001640// This test verifies that when two outgoing audio tracks are using the same
1641// ssrc at different times, they populate stats reports correctly.
1642// TODO(xians): Figure out if it is possible to encapsulate the setup and
1643// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001644TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001645 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001646 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001647 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001648 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001649
Steve Anton3871f6f2018-01-26 10:25:53 -08001650 auto pc = CreatePeerConnection();
1651 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001652
1653 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001654 AddOutgoingAudioTrack(pc, stats.get());
1655 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001656
Steve Anton3871f6f2018-01-26 10:25:53 -08001657 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001658 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001659 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001660 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001661 VoiceMediaInfo voice_info;
1662 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001663
1664 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1665 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001666
xians@webrtc.org01bda202014-07-09 07:38:38 +00001667 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001668 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001669
1670 // Remove the previous audio track from the stream.
1671 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001672 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001673
1674 // Create a new audio track and adds it to the stream and stats.
1675 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001676 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1677 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001678 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001679 stream_->AddTrack(new_audio_track);
1680
Steve Anton3871f6f2018-01-26 10:25:53 -08001681 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1682 stats->ClearUpdateStatsCacheForTest();
1683
1684 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001685 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001686 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1687 false);
1688 VoiceMediaInfo new_voice_info;
1689 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001690 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001691
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001692 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001693 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001694}
1695
sakal43536c32016-10-24 01:46:43 -07001696// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001697TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001698 auto pc = CreatePeerConnection();
1699 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001700
Steve Anton3871f6f2018-01-26 10:25:53 -08001701 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001702
Steve Anton3871f6f2018-01-26 10:25:53 -08001703 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001704 video_sender_info.add_ssrc(1234);
1705 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001706 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001707 VideoMediaInfo video_info;
1708 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001709
1710 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1711 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001712
Steve Anton3871f6f2018-01-26 10:25:53 -08001713 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1714 StatsReports reports;
1715 stats->GetStats(nullptr, &reports);
1716
sakal43536c32016-10-24 01:46:43 -07001717 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1718 ExtractSsrcStatsValue(reports,
1719 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001720 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1721 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001722}
1723
sakale5ba44e2016-10-26 07:09:24 -07001724// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001725TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1726 auto pc = CreatePeerConnection();
1727 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001728
Steve Anton3871f6f2018-01-26 10:25:53 -08001729 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001730
Steve Anton3871f6f2018-01-26 10:25:53 -08001731 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001732 video_receiver_info.add_ssrc(1234);
1733 video_receiver_info.frames_decoded = 10;
Artem Titov8a3ab0e2018-07-27 14:52:57 +00001734 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001735 VideoMediaInfo video_info;
1736 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001737
1738 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1739 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001740
Steve Anton3871f6f2018-01-26 10:25:53 -08001741 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1742 StatsReports reports;
1743 stats->GetStats(nullptr, &reports);
1744
sakale5ba44e2016-10-26 07:09:24 -07001745 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1746 ExtractSsrcStatsValue(reports,
1747 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001748 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1749 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001750}
1751
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001752INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1753
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001754} // namespace webrtc