blob: 53eb2eaa5eaba4677205bd3a9416a3420a6767d1 [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"
Yves Gerey2e00abc2018-10-05 15:39:24 +020025#include "rtc_base/messagedigest.h"
Artem Titova76af0c2018-07-23 17:38:12 +020026#include "rtc_base/third_party/base64/base64.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028
Steve Anton3871f6f2018-01-26 10:25:53 -080029using cricket::ConnectionInfo;
30using cricket::SsrcReceiverInfo;
31using cricket::TransportChannelStats;
32using cricket::VideoMediaInfo;
33using cricket::VideoReceiverInfo;
34using cricket::VideoSenderInfo;
35using cricket::VoiceMediaInfo;
36using cricket::VoiceReceiverInfo;
37using cricket::VoiceSenderInfo;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000039namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
tkchin7d06a8c2016-04-04 14:10:43 -070041namespace internal {
42// This value comes from openssl/tls1.h
43static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
44} // namespace internal
45
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046// Error return values
47const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048
wu@webrtc.org97077a32013-10-25 21:18:33 +000049// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000050const char kLocalTrackId[] = "local_track_id";
51const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020052const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000053
Steve Anton3871f6f2018-01-26 10:25:53 -080054class FakeAudioProcessor : public AudioProcessorInterface {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000055 public:
56 FakeAudioProcessor() {}
57 ~FakeAudioProcessor() {}
58
59 private:
Ivo Creusenae026092017-11-20 13:07:16 +010060 AudioProcessorInterface::AudioProcessorStatistics GetStats(
Ivo Creusen56d46092017-11-24 17:29:59 +010061 bool has_recv_streams) override {
Ivo Creusenae026092017-11-20 13:07:16 +010062 AudioProcessorStatistics stats;
63 stats.typing_noise_detected = true;
Ivo Creusen56d46092017-11-24 17:29:59 +010064 if (has_recv_streams) {
65 stats.apm_statistics.echo_return_loss = 2.0;
66 stats.apm_statistics.echo_return_loss_enhancement = 3.0;
67 stats.apm_statistics.delay_median_ms = 4;
68 stats.apm_statistics.delay_standard_deviation_ms = 5;
69 }
Ivo Creusenae026092017-11-20 13:07:16 +010070 return stats;
71 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000072};
73
Steve Anton3871f6f2018-01-26 10:25:53 -080074class FakeAudioTrack : public MediaStreamTrack<AudioTrackInterface> {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000075 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +000076 explicit FakeAudioTrack(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -080077 : MediaStreamTrack<AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000078 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000079 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -080080 AudioSourceInterface* GetSource() const override { return NULL; }
81 void AddSink(AudioTrackSinkInterface* sink) override {}
82 void RemoveSink(AudioTrackSinkInterface* sink) override {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000083 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000084 *level = 1;
85 return true;
86 }
Steve Anton3871f6f2018-01-26 10:25:53 -080087 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000088 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000089 }
90
91 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000092 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000093};
94
zhihuang6ba3b192016-05-13 11:46:35 -070095// This fake audio processor is used to verify that the undesired initial values
96// (-1) will be filtered out.
Steve Anton3871f6f2018-01-26 10:25:53 -080097class FakeAudioProcessorWithInitValue : public AudioProcessorInterface {
zhihuang6ba3b192016-05-13 11:46:35 -070098 public:
99 FakeAudioProcessorWithInitValue() {}
100 ~FakeAudioProcessorWithInitValue() {}
101
102 private:
Ivo Creusenae026092017-11-20 13:07:16 +0100103 AudioProcessorInterface::AudioProcessorStatistics GetStats(
104 bool /*has_recv_streams*/) override {
105 AudioProcessorStatistics stats;
106 stats.typing_noise_detected = false;
107 return stats;
108 }
zhihuang6ba3b192016-05-13 11:46:35 -0700109};
110
111class FakeAudioTrackWithInitValue
Steve Anton3871f6f2018-01-26 10:25:53 -0800112 : public MediaStreamTrack<AudioTrackInterface> {
zhihuang6ba3b192016-05-13 11:46:35 -0700113 public:
114 explicit FakeAudioTrackWithInitValue(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -0800115 : MediaStreamTrack<AudioTrackInterface>(id),
zhihuang6ba3b192016-05-13 11:46:35 -0700116 processor_(
117 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
118 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -0800119 AudioSourceInterface* GetSource() const override { return NULL; }
120 void AddSink(AudioTrackSinkInterface* sink) override {}
121 void RemoveSink(AudioTrackSinkInterface* sink) override {}
zhihuang6ba3b192016-05-13 11:46:35 -0700122 bool GetSignalLevel(int* level) override {
123 *level = 1;
124 return true;
125 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800126 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
zhihuang6ba3b192016-05-13 11:46:35 -0700127 return processor_;
128 }
129
130 private:
131 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
132};
133
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000134bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000135 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000136 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000137 const StatsReport::Value* v = report->FindValue(name);
138 if (!v)
139 return false;
140 *value = v->ToString();
141 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000142}
143
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000144std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000145 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000146 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000147 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000148 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000149 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000150 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 }
152
153 return kNotFound;
154}
155
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000156StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
157 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000158 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000159 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000160 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000161 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000162
163 // This has assumptions about how the ID is constructed. As is, this is
164 // OK since this is for testing purposes only, but if we ever need this
165 // in production, we should add a generic method that does this.
166 size_t index = value.find('_');
167 EXPECT_NE(index, std::string::npos);
168 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000169 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000170
171 id = StatsReport::NewTypedId(type, value.substr(index + 1));
172 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000173 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000174}
175
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000176StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
177 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000178}
179
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180// Finds the |n|-th report of type |type| in |reports|.
181// |n| starts from 1 for finding the first report.
Yves Gerey665174f2018-06-19 15:03:05 +0200182const StatsReport* FindNthReportByType(const StatsReports& reports,
183 const StatsReport::StatsType& type,
184 int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000186 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 n--;
188 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000189 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 }
191 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000192 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193}
194
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000195const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000196 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000197 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000198 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000199 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000201 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202}
203
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100204std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000205 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000206 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207}
208
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100209std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000210 StatsReport::StatsValueName name) {
Yves Gerey665174f2018-06-19 15:03:05 +0200211 return ExtractStatsValue(StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212}
213
wu@webrtc.org4551b792013-10-09 15:37:36 +0000214std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000215 return rtc::SSLIdentity::DerToPem(
Yves Gerey665174f2018-06-19 15:03:05 +0200216 rtc::kPemTypeCertificate,
217 reinterpret_cast<const unsigned char*>(der.c_str()), der.length());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000218}
219
Yves Gerey665174f2018-06-19 15:03:05 +0200220std::vector<std::string> DersToPems(const std::vector<std::string>& ders) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000221 std::vector<std::string> pems(ders.size());
222 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
223 return pems;
224}
225
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000226void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000227 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000228 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000229 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000230 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000231 size_t i = 0;
232 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000233 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000234 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000235
wu@webrtc.org4551b792013-10-09 15:37:36 +0000236 std::string der_base64;
Yves Gerey665174f2018-06-19 15:03:05 +0200237 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000238 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000239 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000240
241 std::string fingerprint_algorithm;
Yves Gerey665174f2018-06-19 15:03:05 +0200242 EXPECT_TRUE(GetValue(report,
243 StatsReport::kStatsValueNameFingerprintAlgorithm,
244 &fingerprint_algorithm));
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000245 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000247 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
248
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000249 std::string fingerprint;
250 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
251 &fingerprint));
252 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000253
wu@webrtc.org4551b792013-10-09 15:37:36 +0000254 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000255 std::string issuer_id;
Yves Gerey665174f2018-06-19 15:03:05 +0200256 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId, &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000257 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000258 }
259
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000260 cert_id = IdFromCertIdString(issuer_id);
261 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000262 }
263 EXPECT_EQ(ders.size(), i);
264}
265
Yves Gerey665174f2018-06-19 15:03:05 +0200266void VerifyVoiceReceiverInfoReport(const StatsReport* report,
267 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000268 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200269 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioOutputLevel,
270 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200271 EXPECT_EQ(rtc::ToString(info.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200272 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived,
273 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200274 EXPECT_EQ(rtc::ToString(info.bytes_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200275 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
276 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200277 EXPECT_EQ(rtc::ToString(info.jitter_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200278 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterBufferMs,
279 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200280 EXPECT_EQ(rtc::ToString(info.jitter_buffer_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200281 EXPECT_TRUE(GetValue(report,
282 StatsReport::kStatsValueNamePreferredJitterBufferMs,
283 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200284 EXPECT_EQ(rtc::ToString(info.jitter_buffer_preferred_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200285 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCurrentDelayMs,
286 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200287 EXPECT_EQ(rtc::ToString(info.delay_estimate_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200288 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameExpandRate,
289 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200290 EXPECT_EQ(rtc::ToString(info.expand_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200291 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSpeechExpandRate,
292 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200293 EXPECT_EQ(rtc::ToString(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200294 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
295 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200296 EXPECT_EQ(rtc::ToString(info.accelerate_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200297 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
298 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200299 EXPECT_EQ(rtc::ToString(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000300 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
301 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200302 EXPECT_EQ(rtc::ToString(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200303 EXPECT_TRUE(GetValue(report,
304 StatsReport::kStatsValueNameSecondaryDiscardedRate,
305 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200306 EXPECT_EQ(rtc::ToString(info.secondary_discarded_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200307 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived,
308 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200309 EXPECT_EQ(rtc::ToString(info.packets_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200310 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG,
311 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200312 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_silence_generator),
Yves Gerey665174f2018-06-19 15:03:05 +0200313 value_in_report);
314 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTN,
315 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200316 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_neteq), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200317 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingNormal,
318 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200319 EXPECT_EQ(rtc::ToString(info.decoding_normal), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200320 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
321 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200322 EXPECT_EQ(rtc::ToString(info.decoding_plc), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200323 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
324 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200325 EXPECT_EQ(rtc::ToString(info.decoding_cng), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200326 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLCCNG,
327 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200328 EXPECT_EQ(rtc::ToString(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700329 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
330 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200331 EXPECT_EQ(rtc::ToString(info.decoding_muted_output), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700332 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
333 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000334}
335
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000336void VerifyVoiceSenderInfoReport(const StatsReport* report,
337 const cricket::VoiceSenderInfo& sinfo) {
338 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200339 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
340 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000341 EXPECT_EQ(sinfo.codec_name, value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200342 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesSent,
343 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200344 EXPECT_EQ(rtc::ToString(sinfo.bytes_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200345 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsSent,
346 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200347 EXPECT_EQ(rtc::ToString(sinfo.packets_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200348 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
349 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200350 EXPECT_EQ(rtc::ToString(sinfo.packets_lost), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200351 EXPECT_TRUE(
352 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200353 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200354 EXPECT_TRUE(
355 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200356 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200357 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
358 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200359 EXPECT_EQ(rtc::ToString(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100360 if (sinfo.apm_statistics.delay_median_ms) {
361 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
362 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200363 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_median_ms),
Ivo Creusen56d46092017-11-24 17:29:59 +0100364 value_in_report);
365 } else {
366 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
367 &value_in_report));
368 }
369 if (sinfo.apm_statistics.delay_standard_deviation_ms) {
370 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
371 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200372 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_standard_deviation_ms),
373 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100374 } else {
375 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
376 &value_in_report));
377 }
378 if (sinfo.apm_statistics.echo_return_loss) {
379 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
380 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200381 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss),
Ivo Creusen56d46092017-11-24 17:29:59 +0100382 value_in_report);
383 } else {
384 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
385 &value_in_report));
386 }
387 if (sinfo.apm_statistics.echo_return_loss_enhancement) {
388 EXPECT_TRUE(GetValue(report,
389 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
390 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200391 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss_enhancement),
392 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100393 } else {
394 EXPECT_FALSE(GetValue(report,
395 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
396 &value_in_report));
397 }
398 if (sinfo.apm_statistics.residual_echo_likelihood) {
399 EXPECT_TRUE(GetValue(report,
400 StatsReport::kStatsValueNameResidualEchoLikelihood,
401 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200402 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.residual_echo_likelihood),
403 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100404 } else {
405 EXPECT_FALSE(GetValue(report,
406 StatsReport::kStatsValueNameResidualEchoLikelihood,
407 &value_in_report));
408 }
409 if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) {
410 EXPECT_TRUE(GetValue(
411 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
412 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200413 EXPECT_EQ(rtc::ToString(
Ivo Creusen56d46092017-11-24 17:29:59 +0100414 *sinfo.apm_statistics.residual_echo_likelihood_recent_max),
415 value_in_report);
416 } else {
417 EXPECT_FALSE(GetValue(
418 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
419 &value_in_report));
420 }
ivoc8c63a822016-10-21 04:10:03 -0700421 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
422 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200423 EXPECT_EQ(rtc::ToString(sinfo.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200424 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameTypingNoiseState,
425 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000426 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
427 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700428 EXPECT_TRUE(GetValue(report,
429 StatsReport::kStatsValueNameAnaBitrateActionCounter,
430 &value_in_report));
431 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200432 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.bitrate_action_counter),
433 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700434 EXPECT_TRUE(GetValue(report,
435 StatsReport::kStatsValueNameAnaChannelActionCounter,
436 &value_in_report));
437 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200438 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.channel_action_counter),
439 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700440 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
441 &value_in_report));
442 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200443 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.dtx_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700444 value_in_report);
445 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter,
446 &value_in_report));
447 ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200448 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.fec_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700449 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700450 EXPECT_TRUE(GetValue(
451 report, StatsReport::kStatsValueNameAnaFrameLengthIncreaseCounter,
452 &value_in_report));
453 ASSERT_TRUE(sinfo.ana_statistics.frame_length_increase_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200454 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 08:13:19 -0700455 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700456 EXPECT_TRUE(GetValue(
457 report, StatsReport::kStatsValueNameAnaFrameLengthDecreaseCounter,
458 &value_in_report));
459 ASSERT_TRUE(sinfo.ana_statistics.frame_length_decrease_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200460 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_decrease_counter),
ivoc0d0b9122017-09-08 13:24:21 -0700461 value_in_report);
462 EXPECT_TRUE(GetValue(report,
463 StatsReport::kStatsValueNameAnaUplinkPacketLossFraction,
464 &value_in_report));
465 ASSERT_TRUE(sinfo.ana_statistics.uplink_packet_loss_fraction);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200466 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.uplink_packet_loss_fraction),
467 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000468}
469
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000470// Helper methods to avoid duplication of code.
471void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
472 voice_sender_info->add_ssrc(kSsrcOfTrack);
473 voice_sender_info->codec_name = "fake_codec";
474 voice_sender_info->bytes_sent = 100;
475 voice_sender_info->packets_sent = 101;
476 voice_sender_info->rtt_ms = 102;
477 voice_sender_info->fraction_lost = 103;
478 voice_sender_info->jitter_ms = 104;
479 voice_sender_info->packets_lost = 105;
480 voice_sender_info->ext_seqnum = 106;
481 voice_sender_info->audio_level = 107;
Sam Zackrisson5f2ffee2018-11-01 13:51:24 +0100482 voice_sender_info->apm_statistics.echo_return_loss = 108;
483 voice_sender_info->apm_statistics.echo_return_loss_enhancement = 109;
484 voice_sender_info->apm_statistics.delay_median_ms = 110;
485 voice_sender_info->apm_statistics.delay_standard_deviation_ms = 111;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000486 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d46092017-11-24 17:29:59 +0100487 voice_sender_info->ana_statistics.bitrate_action_counter = 112;
488 voice_sender_info->ana_statistics.channel_action_counter = 113;
489 voice_sender_info->ana_statistics.dtx_action_counter = 114;
490 voice_sender_info->ana_statistics.fec_action_counter = 115;
491 voice_sender_info->ana_statistics.frame_length_increase_counter = 116;
492 voice_sender_info->ana_statistics.frame_length_decrease_counter = 117;
493 voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000494}
495
496void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700497 AudioTrackInterface* audio_track,
Ivo Creusen56d46092017-11-24 17:29:59 +0100498 cricket::VoiceSenderInfo* voice_sender_info,
499 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000500 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 10:25:53 -0800501 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
502 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000503 voice_sender_info->typing_noise_detected =
504 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d46092017-11-24 17:29:59 +0100505 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000506}
507
508void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
509 voice_receiver_info->add_ssrc(kSsrcOfTrack);
510 voice_receiver_info->bytes_rcvd = 110;
511 voice_receiver_info->packets_rcvd = 111;
512 voice_receiver_info->packets_lost = 112;
513 voice_receiver_info->fraction_lost = 113;
514 voice_receiver_info->packets_lost = 114;
515 voice_receiver_info->ext_seqnum = 115;
516 voice_receiver_info->jitter_ms = 116;
517 voice_receiver_info->jitter_buffer_ms = 117;
518 voice_receiver_info->jitter_buffer_preferred_ms = 118;
519 voice_receiver_info->delay_estimate_ms = 119;
520 voice_receiver_info->audio_level = 120;
521 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000522 voice_receiver_info->speech_expand_rate = 122;
523 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200524 voice_receiver_info->accelerate_rate = 124;
525 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200526 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000527}
528
Steve Anton3871f6f2018-01-26 10:25:53 -0800529class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000530 public:
Steve Anton3871f6f2018-01-26 10:25:53 -0800531 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 11:33:11 -0700532 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000533
Yves Gerey665174f2018-06-19 15:03:05 +0200534 double GetTimeNow() override { return time_now_; }
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000535
536 private:
537 double time_now_;
538};
539
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540class StatsCollectorTest : public testing::Test {
541 protected:
Steve Anton3871f6f2018-01-26 10:25:53 -0800542 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
543 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 }
545
Steve Anton3871f6f2018-01-26 10:25:53 -0800546 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
547 PeerConnectionInternal* pc) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200548 return absl::make_unique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000549 }
550
Steve Anton3871f6f2018-01-26 10:25:53 -0800551 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
552 StatsCollectorForTest* stats,
553 const VoiceMediaInfo& voice_info,
554 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38 +0000555 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000556 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 10:25:53 -0800557 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000558
559 // Verify the existence of the track report.
Yves Gerey665174f2018-06-19 15:03:05 +0200560 const StatsReport* report =
561 FindNthReportByType(*reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800562 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 15:06:43 -0700563 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +0200564 std::string track_id =
565 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000566 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200567 std::string ssrc_id =
568 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200569 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000570
Yves Gerey665174f2018-06-19 15:03:05 +0200571 std::string media_type =
572 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -0800573 EXPECT_EQ("audio", media_type);
574
xians@webrtc.org01bda202014-07-09 07:38:38 +0000575 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 10:25:53 -0800576 if (!voice_info.senders.empty()) {
577 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000578 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800579 if (!voice_info.receivers.empty()) {
580 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000581 }
582
583 // Verify we get the same result by passing a track to GetStats().
584 StatsReports track_reports; // returned values.
585 stats->GetStats(audio_track, &track_reports);
586 const StatsReport* track_report = FindNthReportByType(
587 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800588 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700589 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000590 track_id = ExtractSsrcStatsValue(track_reports,
591 StatsReport::kStatsValueNameTrackId);
592 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200593 ssrc_id =
594 ExtractSsrcStatsValue(track_reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200595 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 10:25:53 -0800596 if (!voice_info.senders.empty()) {
597 VerifyVoiceSenderInfoReport(track_report, voice_info.senders[0]);
598 }
599 if (!voice_info.receivers.empty()) {
600 VerifyVoiceReceiverInfoReport(track_report, voice_info.receivers[0]);
601 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000602 }
603
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800604 void TestCertificateReports(const rtc::FakeSSLIdentity& local_identity,
605 const std::vector<std::string>& local_ders,
606 const rtc::FakeSSLIdentity& remote_identity,
607 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800608 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000609
Steve Anton3871f6f2018-01-26 10:25:53 -0800610 auto pc = CreatePeerConnection();
611 auto stats = CreateStatsCollector(pc);
612
Steve Anton5b387312018-02-02 16:00:20 -0800613 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000614
615 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800616 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000617 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800618 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700619 channel_stats.ssl_cipher_suite =
620 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800621 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000622
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800623 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 10:12:24 +0200624 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800625 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800626 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 10:25:53 -0800627 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800628 pc->SetRemoteCertChain(kTransportName,
Steve Antonf25303e2018-10-16 15:23:31 -0700629 remote_identity.cert_chain().Clone());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000630
Steve Anton3871f6f2018-01-26 10:25:53 -0800631 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000632
Steve Anton3871f6f2018-01-26 10:25:53 -0800633 StatsReports reports;
634 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000635
Yves Gerey665174f2018-06-19 15:03:05 +0200636 const StatsReport* channel_report =
637 FindNthReportByType(reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800638 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000639
640 // Check local certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200641 std::string local_certificate_id =
642 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
643 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000644 if (local_ders.size() > 0) {
645 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000646 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
647 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000648 } else {
649 EXPECT_EQ(kNotFound, local_certificate_id);
650 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000651
652 // Check remote certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200653 std::string remote_certificate_id =
654 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
655 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000656 if (remote_ders.size() > 0) {
657 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000658 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
659 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000660 } else {
661 EXPECT_EQ(kNotFound, remote_certificate_id);
662 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000663
664 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800665 std::string dtls_cipher_suite =
666 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
667 StatsReport::kStatsValueNameDtlsCipher);
668 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700669 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800670 dtls_cipher_suite);
671 std::string srtp_crypto_suite =
672 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
673 StatsReport::kStatsValueNameSrtpCipher);
674 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
675 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000676 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100677};
678
679class StatsCollectorTrackTest : public StatsCollectorTest,
680 public ::testing::WithParamInterface<bool> {
681 public:
682 // Adds a outgoing video track with a given SSRC into the stats.
683 // If GetParam() returns true, the track is also inserted into the local
684 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800685 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
686 StatsCollectorForTest* stats) {
687 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
688 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100689 if (GetParam()) {
690 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800691 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100692 stream_->AddTrack(track_);
693 stats->AddStream(stream_);
694 } else {
695 stats->AddTrack(track_);
696 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800697 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100698 }
699
700 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800701 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
702 StatsCollectorForTest* stats) {
703 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
704 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100705 if (GetParam()) {
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->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100713 }
714
715 // Adds a outgoing audio track with a given SSRC into the stats,
716 // and register it into the stats object.
717 // If GetParam() returns true, the track is also inserted into the local
718 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800719 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
720 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100721 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
722 if (GetParam()) {
723 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800724 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100725 stream_->AddTrack(audio_track_);
726 stats->AddStream(stream_);
727 } else {
728 stats->AddTrack(audio_track_);
729 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800730 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100731 }
732
733 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800734 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
735 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100736 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
737 if (GetParam()) {
738 if (stream_ == NULL)
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->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100746 }
747
Steve Anton3871f6f2018-01-26 10:25:53 -0800748 rtc::scoped_refptr<MediaStream> stream_;
749 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000750 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751};
752
zhihuang6ba3b192016-05-13 11:46:35 -0700753TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800754 auto pc = CreatePeerConnection();
755 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -0700756
Steve Anton3871f6f2018-01-26 10:25:53 -0800757 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 11:46:35 -0700758
Steve Anton3871f6f2018-01-26 10:25:53 -0800759 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -0700760 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800761 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 11:46:35 -0700762
763 const StatsReport* report =
764 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
765
766 std::string value_in_report;
767 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
768 &value_in_report));
769}
770
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000771// Verify that ExtractDataInfo populates reports.
772TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800773 const std::string kDataChannelLabel = "hacks";
774 constexpr int kDataChannelId = 31337;
775 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000776 DataChannelInterface::DataState::kConnecting);
777
Steve Anton3871f6f2018-01-26 10:25:53 -0800778 auto pc = CreatePeerConnection();
779 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000780
Steve Anton3871f6f2018-01-26 10:25:53 -0800781 InternalDataChannelInit init;
782 init.id = kDataChannelId;
783 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000784
Steve Anton3871f6f2018-01-26 10:25:53 -0800785 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000786 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800787 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000788
789 const StatsReport* report =
790 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
791
Steve Anton3871f6f2018-01-26 10:25:53 -0800792 StatsReport::Id report_id = StatsReport::NewTypedIntId(
793 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000794
Steve Anton3871f6f2018-01-26 10:25:53 -0800795 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000796
Steve Anton3871f6f2018-01-26 10:25:53 -0800797 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
798 EXPECT_EQ(kDataChannelLabel,
799 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
800 StatsReport::kStatsValueNameLabel));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200801 EXPECT_EQ(rtc::ToString(kDataChannelId),
Peter Boström0c4e06b2015-10-07 12:23:21 +0200802 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000803 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 10:25:53 -0800804 EXPECT_EQ(kConnectingString,
805 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
806 StatsReport::kStatsValueNameState));
Yves Gerey665174f2018-06-19 15:03:05 +0200807 EXPECT_EQ("",
808 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
809 StatsReport::kStatsValueNameProtocol));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000810}
811
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100813TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 10:25:53 -0800815 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816
Steve Anton3871f6f2018-01-26 10:25:53 -0800817 auto pc = CreatePeerConnection();
818 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819
Steve Anton3871f6f2018-01-26 10:25:53 -0800820 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000821 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800823 VideoMediaInfo video_info;
824 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800825
826 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
827 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828
Steve Anton3871f6f2018-01-26 10:25:53 -0800829 AddOutgoingVideoTrack(pc, stats.get());
830
831 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
832 StatsReports reports;
833 stats->GetStats(nullptr, &reports);
834
835 EXPECT_EQ(
836 rtc::ToString(kBytesSent),
837 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
Alex Narest42308f62017-06-19 17:58:12 +0200840// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100841TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 17:58:12 +0200842 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
843 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800844 constexpr int64_t kBytesSent = 12345678901234LL;
845 constexpr int kSendBandwidth = 1234567;
846 constexpr int kRecvBandwidth = 12345678;
847 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 17:58:12 +0200848
Steve Anton3871f6f2018-01-26 10:25:53 -0800849 auto pc = CreatePeerConnection();
850 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 17:58:12 +0200851
Steve Anton3871f6f2018-01-26 10:25:53 -0800852 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 17:58:12 +0200853 voice_sender_info.add_ssrc(1234);
854 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800855 VoiceMediaInfo voice_info;
856 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800857
858 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
859 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 17:58:12 +0200860
Steve Anton3871f6f2018-01-26 10:25:53 -0800861 AddOutgoingAudioTrack(pc, stats.get());
862
863 Call::Stats call_stats;
Alex Narest42308f62017-06-19 17:58:12 +0200864 call_stats.send_bandwidth_bps = kSendBandwidth;
865 call_stats.recv_bandwidth_bps = kRecvBandwidth;
866 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800867 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 17:58:12 +0200868
Steve Anton3871f6f2018-01-26 10:25:53 -0800869 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
870 StatsReports reports;
871 stats->GetStats(nullptr, &reports);
872
873 EXPECT_EQ(
874 rtc::ToString(kBytesSent),
875 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
876 EXPECT_EQ(rtc::ToString(kSendBandwidth),
877 ExtractBweStatsValue(
878 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
879 EXPECT_EQ(
880 rtc::ToString(kRecvBandwidth),
881 ExtractBweStatsValue(
882 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
883 EXPECT_EQ(
884 rtc::ToString(kPacerDelay),
885 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
Alex Narest42308f62017-06-19 17:58:12 +0200886}
887
888// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100889TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
891 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800892 constexpr int64_t kBytesSent = 12345678901234LL;
893 constexpr int kSendBandwidth = 1234567;
894 constexpr int kRecvBandwidth = 12345678;
895 constexpr int kPacerDelay = 123;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896
Steve Anton3871f6f2018-01-26 10:25:53 -0800897 auto pc = CreatePeerConnection();
898 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
Steve Anton3871f6f2018-01-26 10:25:53 -0800900 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000901 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800903 VideoMediaInfo video_info;
904 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800905
906 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
907 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908
Steve Anton3871f6f2018-01-26 10:25:53 -0800909 AddOutgoingVideoTrack(pc, stats.get());
910
911 Call::Stats call_stats;
stefanf79ade12017-06-02 06:44:03 -0700912 call_stats.send_bandwidth_bps = kSendBandwidth;
913 call_stats.recv_bandwidth_bps = kRecvBandwidth;
914 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800915 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000916
Steve Anton3871f6f2018-01-26 10:25:53 -0800917 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
918 StatsReports reports;
919 stats->GetStats(nullptr, &reports);
920
921 EXPECT_EQ(
922 rtc::ToString(kBytesSent),
923 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
924 EXPECT_EQ(rtc::ToString(kSendBandwidth),
925 ExtractBweStatsValue(
926 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
927 EXPECT_EQ(
928 rtc::ToString(kRecvBandwidth),
929 ExtractBweStatsValue(
930 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
931 EXPECT_EQ(
932 rtc::ToString(kPacerDelay),
933 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000934}
935
936// This test verifies that an object of type "googSession" always
937// exists in the returned stats.
938TEST_F(StatsCollectorTest, SessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800939 auto pc = CreatePeerConnection();
940 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000941
Steve Anton3871f6f2018-01-26 10:25:53 -0800942 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
943 StatsReports reports;
944 stats->GetStats(nullptr, &reports);
945
946 EXPECT_TRUE(
947 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948}
949
950// This test verifies that only one object of type "googSession" exists
951// in the returned stats.
952TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800953 auto pc = CreatePeerConnection();
954 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000955
Steve Anton3871f6f2018-01-26 10:25:53 -0800956 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
957 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
958 StatsReports reports;
959 stats->GetStats(nullptr, &reports);
960
961 EXPECT_TRUE(
962 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
963 EXPECT_FALSE(
964 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965}
966
967// This test verifies that the empty track report exists in the returned stats
968// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100969TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800970 auto pc = CreatePeerConnection();
971 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000972
Steve Anton5b387312018-02-02 16:00:20 -0800973 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -0800974 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000975
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000976 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000977 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800978 stats->GetStats(nullptr, &reports);
979 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000980 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -0700981 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000982
983 std::string trackValue =
Yves Gerey665174f2018-06-19 15:03:05 +0200984 ExtractStatsValue(StatsReport::kStatsReportTypeTrack, reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000985 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000986 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987}
988
989// This test verifies that the empty track report exists in the returned stats
990// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100991TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800992 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000993
Steve Anton3871f6f2018-01-26 10:25:53 -0800994 auto pc = CreatePeerConnection();
995 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -0700996
Steve Anton3871f6f2018-01-26 10:25:53 -0800997 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000998 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001000 VideoMediaInfo video_info;
1001 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001002
1003 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1004 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005
Steve Anton3871f6f2018-01-26 10:25:53 -08001006 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
Steve Anton3871f6f2018-01-26 10:25:53 -08001008 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001009 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001010 stats->GetStats(nullptr, &reports);
1011
wu@webrtc.org97077a32013-10-25 21:18:33 +00001012 // |reports| should contain at least one session report, one track report,
1013 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001014 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001015 const StatsReport* track_report =
1016 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001017 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001018
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001019 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001020 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001021 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001022 // |reports| should contain at least one session report, one track report,
1023 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001024 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001025 track_report =
1026 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001027 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001028 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029
Yves Gerey665174f2018-06-19 15:03:05 +02001030 std::string ssrc_id =
1031 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001032 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001033
Yves Gerey665174f2018-06-19 15:03:05 +02001034 std::string track_id =
1035 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001036 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001037
Yves Gerey665174f2018-06-19 15:03:05 +02001038 std::string media_type =
1039 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -08001040 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001041}
1042
1043// This test verifies that an SSRC object has the identifier of a Transport
1044// stats object, and that this transport stats object exists in stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001045TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001046 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001047
Steve Anton3871f6f2018-01-26 10:25:53 -08001048 auto pc = CreatePeerConnection();
1049 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001050
Steve Anton3871f6f2018-01-26 10:25:53 -08001051 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001052 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001054 VideoMediaInfo video_info;
1055 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001056
1057 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1058 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001059
Steve Anton3871f6f2018-01-26 10:25:53 -08001060 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061
Steve Anton3871f6f2018-01-26 10:25:53 -08001062 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001063 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001064 stats->GetStats(nullptr, &reports);
1065
Yves Gerey665174f2018-06-19 15:03:05 +02001066 std::string transport_id =
1067 ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports,
1068 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001069 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001070
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001071 // Transport id component ID will always be 1.
1072 // This has assumptions about how the ID is constructed. As is, this is
1073 // OK since this is for testing purposes only, but if we ever need this
1074 // in production, we should add a generic method that does this.
1075 size_t index = transport_id.find('-');
1076 ASSERT_NE(std::string::npos, index);
1077 std::string content = transport_id.substr(index + 1);
1078 index = content.rfind('-');
1079 ASSERT_NE(std::string::npos, index);
1080 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001081 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001082 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001083 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001084 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085}
1086
wu@webrtc.org97077a32013-10-25 21:18:33 +00001087// This test verifies that a remote stats object will not be created for
1088// an outgoing SSRC where remote stats are not returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001089TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001090 auto pc = CreatePeerConnection();
1091 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001092
Steve Anton5b387312018-02-02 16:00:20 -08001093 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001094 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001095
Steve Anton3871f6f2018-01-26 10:25:53 -08001096 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001097 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001098 stats->GetStats(nullptr, &reports);
1099
Yves Gerey665174f2018-06-19 15:03:05 +02001100 const StatsReport* remote_report =
1101 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001102 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001103}
1104
1105// This test verifies that a remote stats object will be created for
1106// an outgoing SSRC where stats are returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001107TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001108 auto pc = CreatePeerConnection();
1109 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001110
Steve Anton3871f6f2018-01-26 10:25:53 -08001111 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001112 remote_ssrc_stats.timestamp = 12345.678;
1113 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 10:25:53 -08001114 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001115 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001116 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 10:25:53 -08001117 VideoMediaInfo video_info;
1118 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001119
1120 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1121 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001122
Steve Anton3871f6f2018-01-26 10:25:53 -08001123 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001124
Steve Anton3871f6f2018-01-26 10:25:53 -08001125 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001126 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001127 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001128
Yves Gerey665174f2018-06-19 15:03:05 +02001129 const StatsReport* remote_report =
1130 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001131 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001132 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001133}
1134
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001135// This test verifies that the empty track report exists in the returned stats
1136// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001137TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001138 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001139
Steve Anton3871f6f2018-01-26 10:25:53 -08001140 auto pc = CreatePeerConnection();
1141 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001142
Steve Anton3871f6f2018-01-26 10:25:53 -08001143 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001144 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001145 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 10:25:53 -08001146 VideoMediaInfo video_info;
1147 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001148
1149 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1150 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001151
Steve Anton3871f6f2018-01-26 10:25:53 -08001152 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001153
Steve Anton3871f6f2018-01-26 10:25:53 -08001154 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001155 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001156 stats->GetStats(nullptr, &reports);
1157
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001158 // |reports| should contain at least one session report, one track report,
1159 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001160 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001161 const StatsReport* track_report =
1162 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001163 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001164 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001165
Yves Gerey665174f2018-06-19 15:03:05 +02001166 std::string ssrc_id =
1167 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001168 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001169
Yves Gerey665174f2018-06-19 15:03:05 +02001170 std::string track_id =
1171 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001172 EXPECT_EQ(kRemoteTrackId, track_id);
1173}
1174
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001175// This test verifies the Ice Candidate report should contain the correct
1176// information from local/remote candidates.
1177TEST_F(StatsCollectorTest, IceCandidateReport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001178 const std::string kTransportName = "transport";
1179 const rtc::AdapterType kNetworkType = rtc::ADAPTER_TYPE_ETHERNET;
1180 constexpr uint32_t kPriority = 1000;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001181
Steve Anton3871f6f2018-01-26 10:25:53 -08001182 constexpr int kLocalPort = 2000;
1183 const std::string kLocalIp = "192.168.0.1";
1184 const rtc::SocketAddress kLocalAddress(kLocalIp, kLocalPort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001185
Steve Anton3871f6f2018-01-26 10:25:53 -08001186 constexpr int kRemotePort = 2001;
1187 const std::string kRemoteIp = "192.168.0.2";
1188 const rtc::SocketAddress kRemoteAddress(kRemoteIp, kRemotePort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001189
Steve Anton3871f6f2018-01-26 10:25:53 -08001190 auto pc = CreatePeerConnection();
1191 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001192
Steve Anton3871f6f2018-01-26 10:25:53 -08001193 cricket::Candidate local;
1194 EXPECT_GT(local.id().length(), 0u);
1195 local.set_type(cricket::LOCAL_PORT_TYPE);
1196 local.set_protocol(cricket::UDP_PROTOCOL_NAME);
1197 local.set_address(kLocalAddress);
1198 local.set_priority(kPriority);
1199 local.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001200
Steve Anton3871f6f2018-01-26 10:25:53 -08001201 cricket::Candidate remote;
1202 EXPECT_GT(remote.id().length(), 0u);
1203 remote.set_type(cricket::PRFLX_PORT_TYPE);
1204 remote.set_protocol(cricket::UDP_PROTOCOL_NAME);
1205 remote.set_address(kRemoteAddress);
1206 remote.set_priority(kPriority);
1207 remote.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001208
Steve Anton3871f6f2018-01-26 10:25:53 -08001209 ConnectionInfo connection_info;
1210 connection_info.local_candidate = local;
1211 connection_info.remote_candidate = remote;
1212 TransportChannelStats channel_stats;
1213 channel_stats.connection_infos.push_back(connection_info);
1214
Steve Anton5b387312018-02-02 16:00:20 -08001215 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 10:25:53 -08001216 pc->SetTransportStats(kTransportName, channel_stats);
1217
1218 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1219 StatsReports reports;
1220 stats->GetStats(nullptr, &reports);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001221
1222 // Verify the local candidate report is populated correctly.
1223 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001224 "Cand-" + local.id(),
1225 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1226 StatsReport::kStatsValueNameLocalCandidateId));
1227 EXPECT_EQ(
1228 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001229 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1230 StatsReport::kStatsValueNameCandidateIPAddress));
1231 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001232 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001233 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1234 StatsReport::kStatsValueNameCandidatePortNumber));
1235 EXPECT_EQ(
1236 cricket::UDP_PROTOCOL_NAME,
1237 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1238 StatsReport::kStatsValueNameCandidateTransportType));
1239 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001240 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001241 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1242 StatsReport::kStatsValueNameCandidatePriority));
1243 EXPECT_EQ(
1244 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1245 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1246 StatsReport::kStatsValueNameCandidateType));
1247 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001248 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001249 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1250 StatsReport::kStatsValueNameCandidateNetworkType));
1251
1252 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 10:25:53 -08001253 EXPECT_EQ(
1254 "Cand-" + remote.id(),
1255 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1256 StatsReport::kStatsValueNameRemoteCandidateId));
1257 EXPECT_EQ(kRemoteIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001258 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1259 reports,
1260 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 10:25:53 -08001261 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001262 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1263 reports,
1264 StatsReport::kStatsValueNameCandidatePortNumber));
1265 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1266 ExtractStatsValue(
1267 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1268 StatsReport::kStatsValueNameCandidateTransportType));
Steve Anton3871f6f2018-01-26 10:25:53 -08001269 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001270 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1271 reports,
1272 StatsReport::kStatsValueNameCandidatePriority));
1273 EXPECT_EQ(
1274 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1275 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1276 reports, StatsReport::kStatsValueNameCandidateType));
1277 EXPECT_EQ(kNotFound,
1278 ExtractStatsValue(
1279 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1280 StatsReport::kStatsValueNameCandidateNetworkType));
1281}
1282
wu@webrtc.org4551b792013-10-09 15:37:36 +00001283// This test verifies that all chained certificates are correctly
1284// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001285TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001286 // Build local certificate chain.
1287 std::vector<std::string> local_ders(5);
1288 local_ders[0] = "These";
1289 local_ders[1] = "are";
1290 local_ders[2] = "some";
1291 local_ders[3] = "der";
1292 local_ders[4] = "values";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001293 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001294
1295 // Build remote certificate chain
1296 std::vector<std::string> remote_ders(4);
1297 remote_ders[0] = "A";
1298 remote_ders[1] = "non-";
1299 remote_ders[2] = "intersecting";
1300 remote_ders[3] = "set";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001301 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001302
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001303 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001304 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001305}
1306
1307// This test verifies that all certificates without chains are correctly
1308// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001309TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001310 // Build local certificate.
1311 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001312 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001313
1314 // Build remote certificate.
1315 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001316 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001317
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001318 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1319 remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001320 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001321}
1322
1323// This test verifies that the stats are generated correctly when no
1324// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001325TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001326 auto pc = CreatePeerConnection();
1327 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001328
Steve Anton3871f6f2018-01-26 10:25:53 -08001329 // This will cause the fake PeerConnection to generate a TransportStats entry
1330 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001331 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001332
Steve Anton3871f6f2018-01-26 10:25:53 -08001333 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1334 StatsReports reports;
1335 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001336
1337 // Check that the local certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001338 std::string local_certificate_id =
1339 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1340 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001341 ASSERT_EQ(kNotFound, local_certificate_id);
1342
1343 // Check that the remote certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001344 std::string remote_certificate_id =
1345 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1346 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001347 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001348
1349 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001350 std::string dtls_cipher_suite =
1351 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1352 StatsReport::kStatsValueNameDtlsCipher);
1353 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1354 std::string srtp_crypto_suite =
1355 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1356 StatsReport::kStatsValueNameSrtpCipher);
1357 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001358}
1359
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001360// This test verifies that a remote certificate with an unsupported digest
1361// algorithm is correctly ignored.
1362TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1363 // Build a local certificate.
1364 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001365 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001366
1367 // Build a remote certificate with an unsupported digest algorithm.
1368 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001369 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
1370 remote_cert.set_digest_algorithm("foobar");
1371 rtc::FakeSSLIdentity remote_identity(remote_cert);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001372
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001373 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1374 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001375}
1376
zhihuang6ba3b192016-05-13 11:46:35 -07001377// This test verifies that the audio/video related stats which are -1 initially
1378// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001379TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001380 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001381 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001382 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001383 }
zhihuang6ba3b192016-05-13 11:46:35 -07001384
Steve Anton3871f6f2018-01-26 10:25:53 -08001385 auto pc = CreatePeerConnection();
1386 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001387
1388 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 11:34:10 -08001389 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 11:46:35 -07001390 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1391 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1392 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001393 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001394 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001395 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001396 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001397 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001398
1399 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001400 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001401 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 11:46:35 -07001402 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1403 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001404 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001405 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001406 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001407 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001408 }
zhihuang6ba3b192016-05-13 11:46:35 -07001409
Steve Anton3871f6f2018-01-26 10:25:53 -08001410 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001411 voice_sender_info.add_ssrc(kSsrcOfTrack);
1412 // These values are set to -1 initially in audio_send_stream.
1413 // The voice_sender_info will read the values from audio_send_stream.
1414 voice_sender_info.rtt_ms = -1;
1415 voice_sender_info.packets_lost = -1;
1416 voice_sender_info.jitter_ms = -1;
1417
1418 // Some of the contents in |voice_sender_info| needs to be updated from the
1419 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001420 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1421 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001422
Steve Anton3871f6f2018-01-26 10:25:53 -08001423 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001424 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1425 voice_receiver_info.capture_start_ntp_time_ms = -1;
1426 voice_receiver_info.audio_level = -1;
1427
1428 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001429 VoiceMediaInfo voice_info;
1430 voice_info.senders.push_back(voice_sender_info);
1431 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001432
Steve Anton5b387312018-02-02 16:00:20 -08001433 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1434 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001435
Steve Anton3871f6f2018-01-26 10:25:53 -08001436 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001437
1438 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001439 StatsReports reports;
1440 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001441 const StatsReport* report =
1442 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001443 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001444 // The -1 will not be added to the stats report.
1445 std::string value_in_report;
1446 EXPECT_FALSE(
1447 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1448 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1449 &value_in_report));
1450 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1451 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001452 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1453 &value_in_report));
1454 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1455 &value_in_report));
1456
1457 // Get stats for the remote track.
1458 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001459 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001460 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001461 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001462 EXPECT_FALSE(GetValue(report,
1463 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1464 &value_in_report));
1465 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1466 &value_in_report));
1467}
1468
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001469// This test verifies that a local stats object can get statistics via
1470// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001471TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001472 auto pc = CreatePeerConnection();
1473 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001474
Steve Anton3871f6f2018-01-26 10:25:53 -08001475 AddOutgoingAudioTrack(pc, stats.get());
1476 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001477
Steve Anton3871f6f2018-01-26 10:25:53 -08001478 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001479 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001480 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1481 VoiceMediaInfo voice_info;
1482 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001483
1484 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1485 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001486
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001487 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001488 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001489
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001490 // Verify that there is no remote report for the local audio track because
1491 // we did not set it up.
Yves Gerey665174f2018-06-19 15:03:05 +02001492 const StatsReport* remote_report =
1493 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001494 EXPECT_TRUE(remote_report == NULL);
1495}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001496
1497// This test verifies that audio receive streams populate stats reports
1498// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001499TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001500 auto pc = CreatePeerConnection();
1501 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001502
Steve Anton3871f6f2018-01-26 10:25:53 -08001503 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001504
Steve Anton3871f6f2018-01-26 10:25:53 -08001505 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001506 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001507 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001508 VoiceMediaInfo voice_info;
1509 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001510
1511 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1512 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001513
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001514 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001515 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001516}
1517
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001518// This test verifies that a local stats object won't update its statistics
1519// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001520TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001521 auto pc = CreatePeerConnection();
1522 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001523
Steve Anton3871f6f2018-01-26 10:25:53 -08001524 AddOutgoingAudioTrack(pc, stats.get());
1525 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001526
Steve Anton3871f6f2018-01-26 10:25:53 -08001527 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001528 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001529 VoiceMediaInfo voice_info;
1530 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001531
Steve Anton5b387312018-02-02 16:00:20 -08001532 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1533 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001534
Steve Anton3871f6f2018-01-26 10:25:53 -08001535 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001536
Steve Anton3871f6f2018-01-26 10:25:53 -08001537 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1538 StatsReports reports;
1539 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001540
1541 // The report will exist since we don't remove them in RemoveStream().
Yves Gerey665174f2018-06-19 15:03:05 +02001542 const StatsReport* report =
1543 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001544 ASSERT_TRUE(report);
1545 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001546 std::string track_id =
1547 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001548 EXPECT_EQ(kLocalTrackId, track_id);
Yves Gerey665174f2018-06-19 15:03:05 +02001549 std::string ssrc_id =
1550 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001551 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001552
1553 // Verifies the values in the track report, no value will be changed by the
1554 // AudioTrackInterface::GetSignalValue() and
Sam Zackrisson28127632018-11-01 11:37:15 +01001555 // AudioProcessorInterface::GetStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001556 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1557}
1558
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001559// This test verifies that when ongoing and incoming audio tracks are using
1560// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001561TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001562 auto pc = CreatePeerConnection();
1563 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001564
1565 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001566 AddOutgoingAudioTrack(pc, stats.get());
1567 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001568
1569 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001570 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001571 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001572 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1573 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001574 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001575 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001576 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001577
Steve Anton3871f6f2018-01-26 10:25:53 -08001578 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001579 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001580 // Some of the contents in |voice_sender_info| needs to be updated from the
1581 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001582 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1583 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001584
Steve Anton3871f6f2018-01-26 10:25:53 -08001585 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001586 InitVoiceReceiverInfo(&voice_receiver_info);
1587
1588 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001589 VoiceMediaInfo voice_info;
1590 voice_info.senders.push_back(voice_sender_info);
1591 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001592
Steve Anton3871f6f2018-01-26 10:25:53 -08001593 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001594 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1595 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001596
Steve Anton3871f6f2018-01-26 10:25:53 -08001597 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001598
1599 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001600 StatsReports reports; // returned values.
1601 stats->GetStats(audio_track_.get(), &reports);
1602
Yves Gerey665174f2018-06-19 15:03:05 +02001603 const StatsReport* track_report =
1604 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001605 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001606 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001607 std::string track_id =
1608 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001609 EXPECT_EQ(kLocalTrackId, track_id);
1610 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1611
1612 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001613 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001614 stats->GetStats(remote_track.get(), &reports);
Yves Gerey665174f2018-06-19 15:03:05 +02001615 track_report =
1616 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001617 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001618 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001619 track_id =
1620 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001621 EXPECT_EQ(kRemoteTrackId, track_id);
1622 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1623}
1624
xians@webrtc.org01bda202014-07-09 07:38:38 +00001625// This test verifies that when two outgoing audio tracks are using the same
1626// ssrc at different times, they populate stats reports correctly.
1627// TODO(xians): Figure out if it is possible to encapsulate the setup and
1628// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001629TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001630 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001631 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001632 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001633 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001634
Steve Anton3871f6f2018-01-26 10:25:53 -08001635 auto pc = CreatePeerConnection();
1636 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001637
1638 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001639 AddOutgoingAudioTrack(pc, stats.get());
1640 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001641
Steve Anton3871f6f2018-01-26 10:25:53 -08001642 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001643 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001644 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001645 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001646 VoiceMediaInfo voice_info;
1647 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001648
1649 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1650 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001651
xians@webrtc.org01bda202014-07-09 07:38:38 +00001652 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001653 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001654
1655 // Remove the previous audio track from the stream.
1656 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001657 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001658
1659 // Create a new audio track and adds it to the stream and stats.
1660 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001661 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1662 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001663 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001664 stream_->AddTrack(new_audio_track);
1665
Steve Anton3871f6f2018-01-26 10:25:53 -08001666 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1667 stats->ClearUpdateStatsCacheForTest();
1668
1669 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001670 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001671 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1672 false);
1673 VoiceMediaInfo new_voice_info;
1674 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001675 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001676
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001677 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001678 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001679}
1680
sakal43536c32016-10-24 01:46:43 -07001681// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001682TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001683 auto pc = CreatePeerConnection();
1684 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001685
Steve Anton3871f6f2018-01-26 10:25:53 -08001686 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001687
Steve Anton3871f6f2018-01-26 10:25:53 -08001688 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001689 video_sender_info.add_ssrc(1234);
1690 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001691 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001692 VideoMediaInfo video_info;
1693 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001694
1695 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1696 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001697
Steve Anton3871f6f2018-01-26 10:25:53 -08001698 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1699 StatsReports reports;
1700 stats->GetStats(nullptr, &reports);
1701
sakal43536c32016-10-24 01:46:43 -07001702 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1703 ExtractSsrcStatsValue(reports,
1704 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001705 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1706 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001707}
1708
sakale5ba44e2016-10-26 07:09:24 -07001709// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001710TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1711 auto pc = CreatePeerConnection();
1712 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001713
Steve Anton3871f6f2018-01-26 10:25:53 -08001714 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001715
Steve Anton3871f6f2018-01-26 10:25:53 -08001716 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001717 video_receiver_info.add_ssrc(1234);
1718 video_receiver_info.frames_decoded = 10;
Artem Titov8a3ab0e2018-07-27 14:52:57 +00001719 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001720 VideoMediaInfo video_info;
1721 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001722
1723 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1724 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001725
Steve Anton3871f6f2018-01-26 10:25:53 -08001726 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1727 StatsReports reports;
1728 stats->GetStats(nullptr, &reports);
1729
sakale5ba44e2016-10-26 07:09:24 -07001730 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1731 ExtractSsrcStatsValue(reports,
1732 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001733 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1734 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001735}
1736
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001737INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1738
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001739} // namespace webrtc