blob: 2a2a2dc9b60519f218347de6ffe23281acaf5d64 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11#include <stdio.h>
12
deadbeefcbecd352015-09-23 11:50:27 -070013#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
Steve Anton36b29d12017-10-30 09:57:42 -070015#include <utility>
deadbeefcbecd352015-09-23 11:50:27 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "pc/statscollector.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "pc/mediastream.h"
20#include "pc/mediastreamtrack.h"
Steve Anton3871f6f2018-01-26 10:25:53 -080021#include "pc/test/fakepeerconnectionforstats.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "pc/test/fakevideotracksource.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "pc/videotrack.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/fakesslidentity.h"
Artem Titova76af0c2018-07-23 17:38:12 +020025#include "rtc_base/third_party/base64/base64.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
Steve Anton3871f6f2018-01-26 10:25:53 -080028using cricket::ConnectionInfo;
29using cricket::SsrcReceiverInfo;
30using cricket::TransportChannelStats;
31using cricket::VideoMediaInfo;
32using cricket::VideoReceiverInfo;
33using cricket::VideoSenderInfo;
34using cricket::VoiceMediaInfo;
35using cricket::VoiceReceiverInfo;
36using cricket::VoiceSenderInfo;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000038namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039
tkchin7d06a8c2016-04-04 14:10:43 -070040namespace internal {
41// This value comes from openssl/tls1.h
42static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
43} // namespace internal
44
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045// Error return values
46const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047
wu@webrtc.org97077a32013-10-25 21:18:33 +000048// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000049const char kLocalTrackId[] = "local_track_id";
50const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020051const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000052
Steve Anton3871f6f2018-01-26 10:25:53 -080053class FakeAudioProcessor : public AudioProcessorInterface {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000054 public:
55 FakeAudioProcessor() {}
56 ~FakeAudioProcessor() {}
57
58 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000059 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000060 stats->typing_noise_detected = true;
61 stats->echo_return_loss = 2;
62 stats->echo_return_loss_enhancement = 3;
63 stats->echo_delay_median_ms = 4;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000064 stats->echo_delay_std_ms = 6;
65 }
Ivo Creusenae026092017-11-20 13:07:16 +010066
67 AudioProcessorInterface::AudioProcessorStatistics GetStats(
Ivo Creusen56d46092017-11-24 17:29:59 +010068 bool has_recv_streams) override {
Ivo Creusenae026092017-11-20 13:07:16 +010069 AudioProcessorStatistics stats;
70 stats.typing_noise_detected = true;
Ivo Creusen56d46092017-11-24 17:29:59 +010071 if (has_recv_streams) {
72 stats.apm_statistics.echo_return_loss = 2.0;
73 stats.apm_statistics.echo_return_loss_enhancement = 3.0;
74 stats.apm_statistics.delay_median_ms = 4;
75 stats.apm_statistics.delay_standard_deviation_ms = 5;
76 }
Ivo Creusenae026092017-11-20 13:07:16 +010077 return stats;
78 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000079};
80
Steve Anton3871f6f2018-01-26 10:25:53 -080081class FakeAudioTrack : public MediaStreamTrack<AudioTrackInterface> {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000082 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +000083 explicit FakeAudioTrack(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -080084 : MediaStreamTrack<AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000085 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000086 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -080087 AudioSourceInterface* GetSource() const override { return NULL; }
88 void AddSink(AudioTrackSinkInterface* sink) override {}
89 void RemoveSink(AudioTrackSinkInterface* sink) override {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000090 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000091 *level = 1;
92 return true;
93 }
Steve Anton3871f6f2018-01-26 10:25:53 -080094 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000095 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000096 }
97
98 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000099 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000100};
101
zhihuang6ba3b192016-05-13 11:46:35 -0700102// This fake audio processor is used to verify that the undesired initial values
103// (-1) will be filtered out.
Steve Anton3871f6f2018-01-26 10:25:53 -0800104class FakeAudioProcessorWithInitValue : public AudioProcessorInterface {
zhihuang6ba3b192016-05-13 11:46:35 -0700105 public:
106 FakeAudioProcessorWithInitValue() {}
107 ~FakeAudioProcessorWithInitValue() {}
108
109 private:
110 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
111 stats->typing_noise_detected = false;
112 stats->echo_return_loss = -100;
113 stats->echo_return_loss_enhancement = -100;
114 stats->echo_delay_median_ms = -1;
zhihuang6ba3b192016-05-13 11:46:35 -0700115 stats->echo_delay_std_ms = -1;
116 }
Ivo Creusenae026092017-11-20 13:07:16 +0100117
118 AudioProcessorInterface::AudioProcessorStatistics GetStats(
119 bool /*has_recv_streams*/) override {
120 AudioProcessorStatistics stats;
121 stats.typing_noise_detected = false;
122 return stats;
123 }
zhihuang6ba3b192016-05-13 11:46:35 -0700124};
125
126class FakeAudioTrackWithInitValue
Steve Anton3871f6f2018-01-26 10:25:53 -0800127 : public MediaStreamTrack<AudioTrackInterface> {
zhihuang6ba3b192016-05-13 11:46:35 -0700128 public:
129 explicit FakeAudioTrackWithInitValue(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -0800130 : MediaStreamTrack<AudioTrackInterface>(id),
zhihuang6ba3b192016-05-13 11:46:35 -0700131 processor_(
132 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
133 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -0800134 AudioSourceInterface* GetSource() const override { return NULL; }
135 void AddSink(AudioTrackSinkInterface* sink) override {}
136 void RemoveSink(AudioTrackSinkInterface* sink) override {}
zhihuang6ba3b192016-05-13 11:46:35 -0700137 bool GetSignalLevel(int* level) override {
138 *level = 1;
139 return true;
140 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800141 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
zhihuang6ba3b192016-05-13 11:46:35 -0700142 return processor_;
143 }
144
145 private:
146 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
147};
148
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000149bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000150 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000151 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000152 const StatsReport::Value* v = report->FindValue(name);
153 if (!v)
154 return false;
155 *value = v->ToString();
156 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000157}
158
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000159std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000160 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000161 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000162 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000163 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000164 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000165 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
167
168 return kNotFound;
169}
170
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000171StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
172 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000173 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000174 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000175 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000176 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000177
178 // This has assumptions about how the ID is constructed. As is, this is
179 // OK since this is for testing purposes only, but if we ever need this
180 // in production, we should add a generic method that does this.
181 size_t index = value.find('_');
182 EXPECT_NE(index, std::string::npos);
183 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000184 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000185
186 id = StatsReport::NewTypedId(type, value.substr(index + 1));
187 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000188 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000189}
190
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000191StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
192 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000193}
194
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195// Finds the |n|-th report of type |type| in |reports|.
196// |n| starts from 1 for finding the first report.
Yves Gerey665174f2018-06-19 15:03:05 +0200197const StatsReport* FindNthReportByType(const StatsReports& reports,
198 const StatsReport::StatsType& type,
199 int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000201 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 n--;
203 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000204 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
206 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000207 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208}
209
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000210const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000211 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000212 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000213 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000214 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000216 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217}
218
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100219std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000220 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000221 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222}
223
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100224std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000225 StatsReport::StatsValueName name) {
Yves Gerey665174f2018-06-19 15:03:05 +0200226 return ExtractStatsValue(StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227}
228
wu@webrtc.org4551b792013-10-09 15:37:36 +0000229std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000230 return rtc::SSLIdentity::DerToPem(
Yves Gerey665174f2018-06-19 15:03:05 +0200231 rtc::kPemTypeCertificate,
232 reinterpret_cast<const unsigned char*>(der.c_str()), der.length());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000233}
234
Yves Gerey665174f2018-06-19 15:03:05 +0200235std::vector<std::string> DersToPems(const std::vector<std::string>& ders) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000236 std::vector<std::string> pems(ders.size());
237 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
238 return pems;
239}
240
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000241void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000242 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000243 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000244 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000245 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000246 size_t i = 0;
247 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000248 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000249 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000250
wu@webrtc.org4551b792013-10-09 15:37:36 +0000251 std::string der_base64;
Yves Gerey665174f2018-06-19 15:03:05 +0200252 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000253 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000254 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000255
256 std::string fingerprint_algorithm;
Yves Gerey665174f2018-06-19 15:03:05 +0200257 EXPECT_TRUE(GetValue(report,
258 StatsReport::kStatsValueNameFingerprintAlgorithm,
259 &fingerprint_algorithm));
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000260 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000261 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000262 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
263
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000264 std::string fingerprint;
265 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
266 &fingerprint));
267 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000268
wu@webrtc.org4551b792013-10-09 15:37:36 +0000269 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000270 std::string issuer_id;
Yves Gerey665174f2018-06-19 15:03:05 +0200271 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId, &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000272 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000273 }
274
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000275 cert_id = IdFromCertIdString(issuer_id);
276 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000277 }
278 EXPECT_EQ(ders.size(), i);
279}
280
Yves Gerey665174f2018-06-19 15:03:05 +0200281void VerifyVoiceReceiverInfoReport(const StatsReport* report,
282 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000283 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200284 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioOutputLevel,
285 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000286 EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200287 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived,
288 &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200289 EXPECT_EQ(rtc::ToString<int64_t>(info.bytes_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200290 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
291 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000292 EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200293 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterBufferMs,
294 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000295 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200296 EXPECT_TRUE(GetValue(report,
297 StatsReport::kStatsValueNamePreferredJitterBufferMs,
298 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000299 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
Yves Gerey665174f2018-06-19 15:03:05 +0200300 value_in_report);
301 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCurrentDelayMs,
302 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000303 EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200304 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameExpandRate,
305 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000306 EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200307 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSpeechExpandRate,
308 &value_in_report));
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000309 EXPECT_EQ(rtc::ToString<float>(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200310 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
311 &value_in_report));
312 EXPECT_EQ(rtc::ToString<float>(info.accelerate_rate), value_in_report);
313 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
314 &value_in_report));
315 EXPECT_EQ(rtc::ToString<float>(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000316 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
317 &value_in_report));
318 EXPECT_EQ(rtc::ToString<float>(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200319 EXPECT_TRUE(GetValue(report,
320 StatsReport::kStatsValueNameSecondaryDiscardedRate,
321 &value_in_report));
322 EXPECT_EQ(rtc::ToString<float>(info.secondary_discarded_rate),
323 value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200324 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived,
325 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000326 EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200327 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG,
328 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000329 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
Yves Gerey665174f2018-06-19 15:03:05 +0200330 value_in_report);
331 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTN,
332 &value_in_report));
333 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq), value_in_report);
334 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingNormal,
335 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000336 EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200337 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
338 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000339 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200340 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
341 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000342 EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200343 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLCCNG,
344 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000345 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700346 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
347 &value_in_report));
348 EXPECT_EQ(rtc::ToString<int>(info.decoding_muted_output), value_in_report);
349 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
350 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000351}
352
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000353void VerifyVoiceSenderInfoReport(const StatsReport* report,
354 const cricket::VoiceSenderInfo& sinfo) {
355 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200356 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
357 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000358 EXPECT_EQ(sinfo.codec_name, value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200359 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesSent,
360 &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200361 EXPECT_EQ(rtc::ToString<int64_t>(sinfo.bytes_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200362 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsSent,
363 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000364 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200365 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
366 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000367 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200368 EXPECT_TRUE(
369 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000370 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200371 EXPECT_TRUE(
372 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000373 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200374 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
375 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000376 EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100377 if (sinfo.apm_statistics.delay_median_ms) {
378 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
379 &value_in_report));
380 EXPECT_EQ(rtc::ToString<int>(*sinfo.apm_statistics.delay_median_ms),
381 value_in_report);
382 } else {
383 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
384 &value_in_report));
385 }
386 if (sinfo.apm_statistics.delay_standard_deviation_ms) {
387 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
388 &value_in_report));
389 EXPECT_EQ(
390 rtc::ToString<int>(*sinfo.apm_statistics.delay_standard_deviation_ms),
391 value_in_report);
392 } else {
393 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
394 &value_in_report));
395 }
396 if (sinfo.apm_statistics.echo_return_loss) {
397 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
398 &value_in_report));
399 EXPECT_EQ(rtc::ToString<int>(*sinfo.apm_statistics.echo_return_loss),
400 value_in_report);
401 } else {
402 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
403 &value_in_report));
404 }
405 if (sinfo.apm_statistics.echo_return_loss_enhancement) {
406 EXPECT_TRUE(GetValue(report,
407 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
408 &value_in_report));
409 EXPECT_EQ(
410 rtc::ToString<int>(*sinfo.apm_statistics.echo_return_loss_enhancement),
411 value_in_report);
412 } else {
413 EXPECT_FALSE(GetValue(report,
414 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
415 &value_in_report));
416 }
417 if (sinfo.apm_statistics.residual_echo_likelihood) {
418 EXPECT_TRUE(GetValue(report,
419 StatsReport::kStatsValueNameResidualEchoLikelihood,
420 &value_in_report));
421 EXPECT_EQ(
422 rtc::ToString<float>(*sinfo.apm_statistics.residual_echo_likelihood),
423 value_in_report);
424 } else {
425 EXPECT_FALSE(GetValue(report,
426 StatsReport::kStatsValueNameResidualEchoLikelihood,
427 &value_in_report));
428 }
429 if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) {
430 EXPECT_TRUE(GetValue(
431 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
432 &value_in_report));
433 EXPECT_EQ(rtc::ToString<float>(
434 *sinfo.apm_statistics.residual_echo_likelihood_recent_max),
435 value_in_report);
436 } else {
437 EXPECT_FALSE(GetValue(
438 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
439 &value_in_report));
440 }
ivoc8c63a822016-10-21 04:10:03 -0700441 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
442 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000443 EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200444 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameTypingNoiseState,
445 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000446 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
447 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700448 EXPECT_TRUE(GetValue(report,
449 StatsReport::kStatsValueNameAnaBitrateActionCounter,
450 &value_in_report));
451 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
452 EXPECT_EQ(
453 rtc::ToString<uint32_t>(*sinfo.ana_statistics.bitrate_action_counter),
454 value_in_report);
455 EXPECT_TRUE(GetValue(report,
456 StatsReport::kStatsValueNameAnaChannelActionCounter,
457 &value_in_report));
458 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
459 EXPECT_EQ(
460 rtc::ToString<uint32_t>(*sinfo.ana_statistics.channel_action_counter),
461 value_in_report);
462 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
463 &value_in_report));
464 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
465 EXPECT_EQ(rtc::ToString<uint32_t>(*sinfo.ana_statistics.dtx_action_counter),
466 value_in_report);
467 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter,
468 &value_in_report));
469 ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter);
470 EXPECT_EQ(rtc::ToString<uint32_t>(*sinfo.ana_statistics.fec_action_counter),
471 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700472 EXPECT_TRUE(GetValue(
473 report, StatsReport::kStatsValueNameAnaFrameLengthIncreaseCounter,
474 &value_in_report));
475 ASSERT_TRUE(sinfo.ana_statistics.frame_length_increase_counter);
ivoce1198e02017-09-08 08:13:19 -0700476 EXPECT_EQ(rtc::ToString<uint32_t>(
ivoc0d0b9122017-09-08 13:24:21 -0700477 *sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 08:13:19 -0700478 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700479 EXPECT_TRUE(GetValue(
480 report, StatsReport::kStatsValueNameAnaFrameLengthDecreaseCounter,
481 &value_in_report));
482 ASSERT_TRUE(sinfo.ana_statistics.frame_length_decrease_counter);
483 EXPECT_EQ(rtc::ToString<uint32_t>(
484 *sinfo.ana_statistics.frame_length_decrease_counter),
485 value_in_report);
486 EXPECT_TRUE(GetValue(report,
487 StatsReport::kStatsValueNameAnaUplinkPacketLossFraction,
488 &value_in_report));
489 ASSERT_TRUE(sinfo.ana_statistics.uplink_packet_loss_fraction);
490 EXPECT_EQ(
491 rtc::ToString<float>(*sinfo.ana_statistics.uplink_packet_loss_fraction),
492 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000493}
494
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000495// Helper methods to avoid duplication of code.
496void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
497 voice_sender_info->add_ssrc(kSsrcOfTrack);
498 voice_sender_info->codec_name = "fake_codec";
499 voice_sender_info->bytes_sent = 100;
500 voice_sender_info->packets_sent = 101;
501 voice_sender_info->rtt_ms = 102;
502 voice_sender_info->fraction_lost = 103;
503 voice_sender_info->jitter_ms = 104;
504 voice_sender_info->packets_lost = 105;
505 voice_sender_info->ext_seqnum = 106;
506 voice_sender_info->audio_level = 107;
507 voice_sender_info->echo_return_loss = 108;
508 voice_sender_info->echo_return_loss_enhancement = 109;
509 voice_sender_info->echo_delay_median_ms = 110;
510 voice_sender_info->echo_delay_std_ms = 111;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000511 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d46092017-11-24 17:29:59 +0100512 voice_sender_info->ana_statistics.bitrate_action_counter = 112;
513 voice_sender_info->ana_statistics.channel_action_counter = 113;
514 voice_sender_info->ana_statistics.dtx_action_counter = 114;
515 voice_sender_info->ana_statistics.fec_action_counter = 115;
516 voice_sender_info->ana_statistics.frame_length_increase_counter = 116;
517 voice_sender_info->ana_statistics.frame_length_decrease_counter = 117;
518 voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000519}
520
521void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700522 AudioTrackInterface* audio_track,
Ivo Creusen56d46092017-11-24 17:29:59 +0100523 cricket::VoiceSenderInfo* voice_sender_info,
524 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000525 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 10:25:53 -0800526 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
527 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000528 voice_sender_info->typing_noise_detected =
529 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d46092017-11-24 17:29:59 +0100530 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000531}
532
533void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
534 voice_receiver_info->add_ssrc(kSsrcOfTrack);
535 voice_receiver_info->bytes_rcvd = 110;
536 voice_receiver_info->packets_rcvd = 111;
537 voice_receiver_info->packets_lost = 112;
538 voice_receiver_info->fraction_lost = 113;
539 voice_receiver_info->packets_lost = 114;
540 voice_receiver_info->ext_seqnum = 115;
541 voice_receiver_info->jitter_ms = 116;
542 voice_receiver_info->jitter_buffer_ms = 117;
543 voice_receiver_info->jitter_buffer_preferred_ms = 118;
544 voice_receiver_info->delay_estimate_ms = 119;
545 voice_receiver_info->audio_level = 120;
546 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000547 voice_receiver_info->speech_expand_rate = 122;
548 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200549 voice_receiver_info->accelerate_rate = 124;
550 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200551 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000552}
553
Steve Anton3871f6f2018-01-26 10:25:53 -0800554class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000555 public:
Steve Anton3871f6f2018-01-26 10:25:53 -0800556 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 11:33:11 -0700557 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000558
Yves Gerey665174f2018-06-19 15:03:05 +0200559 double GetTimeNow() override { return time_now_; }
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000560
561 private:
562 double time_now_;
563};
564
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565class StatsCollectorTest : public testing::Test {
566 protected:
Steve Anton3871f6f2018-01-26 10:25:53 -0800567 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
568 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569 }
570
Steve Anton3871f6f2018-01-26 10:25:53 -0800571 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
572 PeerConnectionInternal* pc) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200573 return absl::make_unique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000574 }
575
Steve Anton3871f6f2018-01-26 10:25:53 -0800576 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
577 StatsCollectorForTest* stats,
578 const VoiceMediaInfo& voice_info,
579 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38 +0000580 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000581 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 10:25:53 -0800582 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000583
584 // Verify the existence of the track report.
Yves Gerey665174f2018-06-19 15:03:05 +0200585 const StatsReport* report =
586 FindNthReportByType(*reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800587 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 15:06:43 -0700588 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +0200589 std::string track_id =
590 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000591 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200592 std::string ssrc_id =
593 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200594 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000595
Yves Gerey665174f2018-06-19 15:03:05 +0200596 std::string media_type =
597 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -0800598 EXPECT_EQ("audio", media_type);
599
xians@webrtc.org01bda202014-07-09 07:38:38 +0000600 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 10:25:53 -0800601 if (!voice_info.senders.empty()) {
602 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000603 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800604 if (!voice_info.receivers.empty()) {
605 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000606 }
607
608 // Verify we get the same result by passing a track to GetStats().
609 StatsReports track_reports; // returned values.
610 stats->GetStats(audio_track, &track_reports);
611 const StatsReport* track_report = FindNthReportByType(
612 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800613 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700614 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000615 track_id = ExtractSsrcStatsValue(track_reports,
616 StatsReport::kStatsValueNameTrackId);
617 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200618 ssrc_id =
619 ExtractSsrcStatsValue(track_reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200620 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 10:25:53 -0800621 if (!voice_info.senders.empty()) {
622 VerifyVoiceSenderInfoReport(track_report, voice_info.senders[0]);
623 }
624 if (!voice_info.receivers.empty()) {
625 VerifyVoiceReceiverInfoReport(track_report, voice_info.receivers[0]);
626 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000627 }
628
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800629 void TestCertificateReports(const rtc::FakeSSLIdentity& local_identity,
630 const std::vector<std::string>& local_ders,
631 const rtc::FakeSSLIdentity& remote_identity,
632 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800633 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000634
Steve Anton3871f6f2018-01-26 10:25:53 -0800635 auto pc = CreatePeerConnection();
636 auto stats = CreateStatsCollector(pc);
637
Steve Anton5b387312018-02-02 16:00:20 -0800638 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000639
640 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800641 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000642 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800643 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700644 channel_stats.ssl_cipher_suite =
645 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800646 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000647
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800648 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 10:12:24 +0200649 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800650 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800651 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 10:25:53 -0800652 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800653 pc->SetRemoteCertChain(kTransportName,
654 remote_identity.cert_chain().UniqueCopy());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000655
Steve Anton3871f6f2018-01-26 10:25:53 -0800656 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000657
Steve Anton3871f6f2018-01-26 10:25:53 -0800658 StatsReports reports;
659 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000660
Yves Gerey665174f2018-06-19 15:03:05 +0200661 const StatsReport* channel_report =
662 FindNthReportByType(reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800663 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000664
665 // Check local certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200666 std::string local_certificate_id =
667 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
668 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000669 if (local_ders.size() > 0) {
670 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000671 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
672 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000673 } else {
674 EXPECT_EQ(kNotFound, local_certificate_id);
675 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000676
677 // Check remote certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200678 std::string remote_certificate_id =
679 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
680 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000681 if (remote_ders.size() > 0) {
682 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000683 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
684 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000685 } else {
686 EXPECT_EQ(kNotFound, remote_certificate_id);
687 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000688
689 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800690 std::string dtls_cipher_suite =
691 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
692 StatsReport::kStatsValueNameDtlsCipher);
693 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700694 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800695 dtls_cipher_suite);
696 std::string srtp_crypto_suite =
697 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
698 StatsReport::kStatsValueNameSrtpCipher);
699 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
700 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000701 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100702};
703
704class StatsCollectorTrackTest : public StatsCollectorTest,
705 public ::testing::WithParamInterface<bool> {
706 public:
707 // Adds a outgoing video track with a given SSRC into the stats.
708 // If GetParam() returns true, the track is also inserted into the local
709 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800710 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
711 StatsCollectorForTest* stats) {
712 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
713 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100714 if (GetParam()) {
715 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800716 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100717 stream_->AddTrack(track_);
718 stats->AddStream(stream_);
719 } else {
720 stats->AddTrack(track_);
721 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800722 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100723 }
724
725 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800726 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
727 StatsCollectorForTest* stats) {
728 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
729 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100730 if (GetParam()) {
Seth Hampson845e8782018-03-02 11:34:10 -0800731 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100732 stream_->AddTrack(track_);
733 stats->AddStream(stream_);
734 } else {
735 stats->AddTrack(track_);
736 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800737 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100738 }
739
740 // Adds a outgoing audio track with a given SSRC into the stats,
741 // and register it into the stats object.
742 // If GetParam() returns true, the track is also inserted into the local
743 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800744 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
745 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100746 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
747 if (GetParam()) {
748 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800749 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100750 stream_->AddTrack(audio_track_);
751 stats->AddStream(stream_);
752 } else {
753 stats->AddTrack(audio_track_);
754 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800755 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100756 }
757
758 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800759 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
760 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100761 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
762 if (GetParam()) {
763 if (stream_ == NULL)
Seth Hampson845e8782018-03-02 11:34:10 -0800764 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100765 stream_->AddTrack(audio_track_);
766 stats->AddStream(stream_);
767 } else {
768 stats->AddTrack(audio_track_);
769 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800770 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100771 }
772
Steve Anton3871f6f2018-01-26 10:25:53 -0800773 rtc::scoped_refptr<MediaStream> stream_;
774 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000775 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776};
777
zhihuang6ba3b192016-05-13 11:46:35 -0700778TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800779 auto pc = CreatePeerConnection();
780 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -0700781
Steve Anton3871f6f2018-01-26 10:25:53 -0800782 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 11:46:35 -0700783
Steve Anton3871f6f2018-01-26 10:25:53 -0800784 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -0700785 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800786 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 11:46:35 -0700787
788 const StatsReport* report =
789 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
790
791 std::string value_in_report;
792 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
793 &value_in_report));
794}
795
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000796// Verify that ExtractDataInfo populates reports.
797TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800798 const std::string kDataChannelLabel = "hacks";
799 constexpr int kDataChannelId = 31337;
800 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000801 DataChannelInterface::DataState::kConnecting);
802
Steve Anton3871f6f2018-01-26 10:25:53 -0800803 auto pc = CreatePeerConnection();
804 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000805
Steve Anton3871f6f2018-01-26 10:25:53 -0800806 InternalDataChannelInit init;
807 init.id = kDataChannelId;
808 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000809
Steve Anton3871f6f2018-01-26 10:25:53 -0800810 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000811 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800812 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000813
814 const StatsReport* report =
815 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
816
Steve Anton3871f6f2018-01-26 10:25:53 -0800817 StatsReport::Id report_id = StatsReport::NewTypedIntId(
818 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000819
Steve Anton3871f6f2018-01-26 10:25:53 -0800820 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000821
Steve Anton3871f6f2018-01-26 10:25:53 -0800822 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
823 EXPECT_EQ(kDataChannelLabel,
824 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
825 StatsReport::kStatsValueNameLabel));
826 EXPECT_EQ(rtc::ToString<int64_t>(kDataChannelId),
Peter Boström0c4e06b2015-10-07 12:23:21 +0200827 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000828 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 10:25:53 -0800829 EXPECT_EQ(kConnectingString,
830 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
831 StatsReport::kStatsValueNameState));
Yves Gerey665174f2018-06-19 15:03:05 +0200832 EXPECT_EQ("",
833 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
834 StatsReport::kStatsValueNameProtocol));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000835}
836
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100838TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 10:25:53 -0800840 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841
Steve Anton3871f6f2018-01-26 10:25:53 -0800842 auto pc = CreatePeerConnection();
843 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844
Steve Anton3871f6f2018-01-26 10:25:53 -0800845 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000846 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800848 VideoMediaInfo video_info;
849 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800850
851 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
852 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853
Steve Anton3871f6f2018-01-26 10:25:53 -0800854 AddOutgoingVideoTrack(pc, stats.get());
855
856 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
857 StatsReports reports;
858 stats->GetStats(nullptr, &reports);
859
860 EXPECT_EQ(
861 rtc::ToString(kBytesSent),
862 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863}
864
Alex Narest42308f62017-06-19 17:58:12 +0200865// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100866TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 17:58:12 +0200867 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
868 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800869 constexpr int64_t kBytesSent = 12345678901234LL;
870 constexpr int kSendBandwidth = 1234567;
871 constexpr int kRecvBandwidth = 12345678;
872 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 17:58:12 +0200873
Steve Anton3871f6f2018-01-26 10:25:53 -0800874 auto pc = CreatePeerConnection();
875 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 17:58:12 +0200876
Steve Anton3871f6f2018-01-26 10:25:53 -0800877 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 17:58:12 +0200878 voice_sender_info.add_ssrc(1234);
879 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800880 VoiceMediaInfo voice_info;
881 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800882
883 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
884 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 17:58:12 +0200885
Steve Anton3871f6f2018-01-26 10:25:53 -0800886 AddOutgoingAudioTrack(pc, stats.get());
887
888 Call::Stats call_stats;
Alex Narest42308f62017-06-19 17:58:12 +0200889 call_stats.send_bandwidth_bps = kSendBandwidth;
890 call_stats.recv_bandwidth_bps = kRecvBandwidth;
891 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800892 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 17:58:12 +0200893
Steve Anton3871f6f2018-01-26 10:25:53 -0800894 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
895 StatsReports reports;
896 stats->GetStats(nullptr, &reports);
897
898 EXPECT_EQ(
899 rtc::ToString(kBytesSent),
900 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
901 EXPECT_EQ(rtc::ToString(kSendBandwidth),
902 ExtractBweStatsValue(
903 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
904 EXPECT_EQ(
905 rtc::ToString(kRecvBandwidth),
906 ExtractBweStatsValue(
907 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
908 EXPECT_EQ(
909 rtc::ToString(kPacerDelay),
910 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
Alex Narest42308f62017-06-19 17:58:12 +0200911}
912
913// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100914TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
916 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800917 constexpr int64_t kBytesSent = 12345678901234LL;
918 constexpr int kSendBandwidth = 1234567;
919 constexpr int kRecvBandwidth = 12345678;
920 constexpr int kPacerDelay = 123;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921
Steve Anton3871f6f2018-01-26 10:25:53 -0800922 auto pc = CreatePeerConnection();
923 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924
Steve Anton3871f6f2018-01-26 10:25:53 -0800925 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000926 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800928 VideoMediaInfo video_info;
929 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800930
931 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
932 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
Steve Anton3871f6f2018-01-26 10:25:53 -0800934 AddOutgoingVideoTrack(pc, stats.get());
935
936 Call::Stats call_stats;
stefanf79ade12017-06-02 06:44:03 -0700937 call_stats.send_bandwidth_bps = kSendBandwidth;
938 call_stats.recv_bandwidth_bps = kRecvBandwidth;
939 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800940 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000941
Steve Anton3871f6f2018-01-26 10:25:53 -0800942 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
943 StatsReports reports;
944 stats->GetStats(nullptr, &reports);
945
946 EXPECT_EQ(
947 rtc::ToString(kBytesSent),
948 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
949 EXPECT_EQ(rtc::ToString(kSendBandwidth),
950 ExtractBweStatsValue(
951 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
952 EXPECT_EQ(
953 rtc::ToString(kRecvBandwidth),
954 ExtractBweStatsValue(
955 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
956 EXPECT_EQ(
957 rtc::ToString(kPacerDelay),
958 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959}
960
961// This test verifies that an object of type "googSession" always
962// exists in the returned stats.
963TEST_F(StatsCollectorTest, SessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800964 auto pc = CreatePeerConnection();
965 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000966
Steve Anton3871f6f2018-01-26 10:25:53 -0800967 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
968 StatsReports reports;
969 stats->GetStats(nullptr, &reports);
970
971 EXPECT_TRUE(
972 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973}
974
975// This test verifies that only one object of type "googSession" exists
976// in the returned stats.
977TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800978 auto pc = CreatePeerConnection();
979 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000980
Steve Anton3871f6f2018-01-26 10:25:53 -0800981 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
982 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
983 StatsReports reports;
984 stats->GetStats(nullptr, &reports);
985
986 EXPECT_TRUE(
987 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
988 EXPECT_FALSE(
989 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000990}
991
992// This test verifies that the empty track report exists in the returned stats
993// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100994TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800995 auto pc = CreatePeerConnection();
996 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000997
Steve Anton5b387312018-02-02 16:00:20 -0800998 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -0800999 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001000
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001001 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001002 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001003 stats->GetStats(nullptr, &reports);
1004 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001005 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -07001006 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007
1008 std::string trackValue =
Yves Gerey665174f2018-06-19 15:03:05 +02001009 ExtractStatsValue(StatsReport::kStatsReportTypeTrack, reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001010 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001011 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012}
1013
1014// This test verifies that the empty track report exists in the returned stats
1015// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001016TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001017 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001018
Steve Anton3871f6f2018-01-26 10:25:53 -08001019 auto pc = CreatePeerConnection();
1020 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001021
Steve Anton3871f6f2018-01-26 10:25:53 -08001022 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001023 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001025 VideoMediaInfo video_info;
1026 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001027
1028 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1029 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001030
Steve Anton3871f6f2018-01-26 10:25:53 -08001031 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032
Steve Anton3871f6f2018-01-26 10:25:53 -08001033 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001034 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001035 stats->GetStats(nullptr, &reports);
1036
wu@webrtc.org97077a32013-10-25 21:18:33 +00001037 // |reports| should contain at least one session report, one track report,
1038 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001039 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001040 const StatsReport* track_report =
1041 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001042 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001044 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001045 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001046 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001047 // |reports| should contain at least one session report, one track report,
1048 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001049 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001050 track_report =
1051 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001052 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001053 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054
Yves Gerey665174f2018-06-19 15:03:05 +02001055 std::string ssrc_id =
1056 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001057 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001058
Yves Gerey665174f2018-06-19 15:03:05 +02001059 std::string track_id =
1060 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001061 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001062
Yves Gerey665174f2018-06-19 15:03:05 +02001063 std::string media_type =
1064 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -08001065 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001066}
1067
1068// This test verifies that an SSRC object has the identifier of a Transport
1069// stats object, and that this transport stats object exists in stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001070TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001071 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001072
Steve Anton3871f6f2018-01-26 10:25:53 -08001073 auto pc = CreatePeerConnection();
1074 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001075
Steve Anton3871f6f2018-01-26 10:25:53 -08001076 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001077 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001078 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001079 VideoMediaInfo video_info;
1080 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001081
1082 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1083 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001084
Steve Anton3871f6f2018-01-26 10:25:53 -08001085 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001086
Steve Anton3871f6f2018-01-26 10:25:53 -08001087 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001088 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001089 stats->GetStats(nullptr, &reports);
1090
Yves Gerey665174f2018-06-19 15:03:05 +02001091 std::string transport_id =
1092 ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports,
1093 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001094 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001095
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001096 // Transport id component ID will always be 1.
1097 // This has assumptions about how the ID is constructed. As is, this is
1098 // OK since this is for testing purposes only, but if we ever need this
1099 // in production, we should add a generic method that does this.
1100 size_t index = transport_id.find('-');
1101 ASSERT_NE(std::string::npos, index);
1102 std::string content = transport_id.substr(index + 1);
1103 index = content.rfind('-');
1104 ASSERT_NE(std::string::npos, index);
1105 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001106 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001107 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001108 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001109 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110}
1111
wu@webrtc.org97077a32013-10-25 21:18:33 +00001112// This test verifies that a remote stats object will not be created for
1113// an outgoing SSRC where remote stats are not returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001114TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001115 auto pc = CreatePeerConnection();
1116 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001117
Steve Anton5b387312018-02-02 16:00:20 -08001118 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001119 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001120
Steve Anton3871f6f2018-01-26 10:25:53 -08001121 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001122 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001123 stats->GetStats(nullptr, &reports);
1124
Yves Gerey665174f2018-06-19 15:03:05 +02001125 const StatsReport* remote_report =
1126 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001127 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001128}
1129
1130// This test verifies that a remote stats object will be created for
1131// an outgoing SSRC where stats are returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001132TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001133 auto pc = CreatePeerConnection();
1134 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001135
Steve Anton3871f6f2018-01-26 10:25:53 -08001136 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001137 remote_ssrc_stats.timestamp = 12345.678;
1138 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 10:25:53 -08001139 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001140 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001141 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 10:25:53 -08001142 VideoMediaInfo video_info;
1143 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001144
1145 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1146 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001147
Steve Anton3871f6f2018-01-26 10:25:53 -08001148 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001149
Steve Anton3871f6f2018-01-26 10:25:53 -08001150 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001151 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001152 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001153
Yves Gerey665174f2018-06-19 15:03:05 +02001154 const StatsReport* remote_report =
1155 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001156 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001157 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001158}
1159
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001160// This test verifies that the empty track report exists in the returned stats
1161// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001162TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001163 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001164
Steve Anton3871f6f2018-01-26 10:25:53 -08001165 auto pc = CreatePeerConnection();
1166 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001167
Steve Anton3871f6f2018-01-26 10:25:53 -08001168 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001169 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001170 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 10:25:53 -08001171 VideoMediaInfo video_info;
1172 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001173
1174 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1175 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001176
Steve Anton3871f6f2018-01-26 10:25:53 -08001177 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001178
Steve Anton3871f6f2018-01-26 10:25:53 -08001179 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001180 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001181 stats->GetStats(nullptr, &reports);
1182
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001183 // |reports| should contain at least one session report, one track report,
1184 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001185 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001186 const StatsReport* track_report =
1187 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001188 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001189 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001190
Yves Gerey665174f2018-06-19 15:03:05 +02001191 std::string ssrc_id =
1192 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001193 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001194
Yves Gerey665174f2018-06-19 15:03:05 +02001195 std::string track_id =
1196 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001197 EXPECT_EQ(kRemoteTrackId, track_id);
1198}
1199
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001200// This test verifies the Ice Candidate report should contain the correct
1201// information from local/remote candidates.
1202TEST_F(StatsCollectorTest, IceCandidateReport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001203 const std::string kTransportName = "transport";
1204 const rtc::AdapterType kNetworkType = rtc::ADAPTER_TYPE_ETHERNET;
1205 constexpr uint32_t kPriority = 1000;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001206
Steve Anton3871f6f2018-01-26 10:25:53 -08001207 constexpr int kLocalPort = 2000;
1208 const std::string kLocalIp = "192.168.0.1";
1209 const rtc::SocketAddress kLocalAddress(kLocalIp, kLocalPort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001210
Steve Anton3871f6f2018-01-26 10:25:53 -08001211 constexpr int kRemotePort = 2001;
1212 const std::string kRemoteIp = "192.168.0.2";
1213 const rtc::SocketAddress kRemoteAddress(kRemoteIp, kRemotePort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001214
Steve Anton3871f6f2018-01-26 10:25:53 -08001215 auto pc = CreatePeerConnection();
1216 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001217
Steve Anton3871f6f2018-01-26 10:25:53 -08001218 cricket::Candidate local;
1219 EXPECT_GT(local.id().length(), 0u);
1220 local.set_type(cricket::LOCAL_PORT_TYPE);
1221 local.set_protocol(cricket::UDP_PROTOCOL_NAME);
1222 local.set_address(kLocalAddress);
1223 local.set_priority(kPriority);
1224 local.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001225
Steve Anton3871f6f2018-01-26 10:25:53 -08001226 cricket::Candidate remote;
1227 EXPECT_GT(remote.id().length(), 0u);
1228 remote.set_type(cricket::PRFLX_PORT_TYPE);
1229 remote.set_protocol(cricket::UDP_PROTOCOL_NAME);
1230 remote.set_address(kRemoteAddress);
1231 remote.set_priority(kPriority);
1232 remote.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001233
Steve Anton3871f6f2018-01-26 10:25:53 -08001234 ConnectionInfo connection_info;
1235 connection_info.local_candidate = local;
1236 connection_info.remote_candidate = remote;
1237 TransportChannelStats channel_stats;
1238 channel_stats.connection_infos.push_back(connection_info);
1239
Steve Anton5b387312018-02-02 16:00:20 -08001240 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 10:25:53 -08001241 pc->SetTransportStats(kTransportName, channel_stats);
1242
1243 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1244 StatsReports reports;
1245 stats->GetStats(nullptr, &reports);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001246
1247 // Verify the local candidate report is populated correctly.
1248 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001249 "Cand-" + local.id(),
1250 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1251 StatsReport::kStatsValueNameLocalCandidateId));
1252 EXPECT_EQ(
1253 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001254 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1255 StatsReport::kStatsValueNameCandidateIPAddress));
1256 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001257 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001258 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1259 StatsReport::kStatsValueNameCandidatePortNumber));
1260 EXPECT_EQ(
1261 cricket::UDP_PROTOCOL_NAME,
1262 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1263 StatsReport::kStatsValueNameCandidateTransportType));
1264 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001265 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001266 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1267 StatsReport::kStatsValueNameCandidatePriority));
1268 EXPECT_EQ(
1269 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1270 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1271 StatsReport::kStatsValueNameCandidateType));
1272 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001273 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001274 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1275 StatsReport::kStatsValueNameCandidateNetworkType));
1276
1277 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 10:25:53 -08001278 EXPECT_EQ(
1279 "Cand-" + remote.id(),
1280 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1281 StatsReport::kStatsValueNameRemoteCandidateId));
1282 EXPECT_EQ(kRemoteIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001283 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1284 reports,
1285 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 10:25:53 -08001286 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001287 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1288 reports,
1289 StatsReport::kStatsValueNameCandidatePortNumber));
1290 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1291 ExtractStatsValue(
1292 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1293 StatsReport::kStatsValueNameCandidateTransportType));
Steve Anton3871f6f2018-01-26 10:25:53 -08001294 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001295 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1296 reports,
1297 StatsReport::kStatsValueNameCandidatePriority));
1298 EXPECT_EQ(
1299 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1300 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1301 reports, StatsReport::kStatsValueNameCandidateType));
1302 EXPECT_EQ(kNotFound,
1303 ExtractStatsValue(
1304 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1305 StatsReport::kStatsValueNameCandidateNetworkType));
1306}
1307
wu@webrtc.org4551b792013-10-09 15:37:36 +00001308// This test verifies that all chained certificates are correctly
1309// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001310TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001311 // Build local certificate chain.
1312 std::vector<std::string> local_ders(5);
1313 local_ders[0] = "These";
1314 local_ders[1] = "are";
1315 local_ders[2] = "some";
1316 local_ders[3] = "der";
1317 local_ders[4] = "values";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001318 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001319
1320 // Build remote certificate chain
1321 std::vector<std::string> remote_ders(4);
1322 remote_ders[0] = "A";
1323 remote_ders[1] = "non-";
1324 remote_ders[2] = "intersecting";
1325 remote_ders[3] = "set";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001326 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001327
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001328 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001329 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001330}
1331
1332// This test verifies that all certificates without chains are correctly
1333// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001334TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001335 // Build local certificate.
1336 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001337 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001338
1339 // Build remote certificate.
1340 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001341 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001342
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001343 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1344 remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001345 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001346}
1347
1348// This test verifies that the stats are generated correctly when no
1349// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001350TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001351 auto pc = CreatePeerConnection();
1352 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001353
Steve Anton3871f6f2018-01-26 10:25:53 -08001354 // This will cause the fake PeerConnection to generate a TransportStats entry
1355 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001356 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001357
Steve Anton3871f6f2018-01-26 10:25:53 -08001358 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1359 StatsReports reports;
1360 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001361
1362 // Check that the local certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001363 std::string local_certificate_id =
1364 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1365 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001366 ASSERT_EQ(kNotFound, local_certificate_id);
1367
1368 // Check that the remote certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001369 std::string remote_certificate_id =
1370 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1371 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001372 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001373
1374 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001375 std::string dtls_cipher_suite =
1376 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1377 StatsReport::kStatsValueNameDtlsCipher);
1378 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1379 std::string srtp_crypto_suite =
1380 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1381 StatsReport::kStatsValueNameSrtpCipher);
1382 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001383}
1384
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001385// This test verifies that a remote certificate with an unsupported digest
1386// algorithm is correctly ignored.
1387TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1388 // Build a local certificate.
1389 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001390 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001391
1392 // Build a remote certificate with an unsupported digest algorithm.
1393 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001394 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
1395 remote_cert.set_digest_algorithm("foobar");
1396 rtc::FakeSSLIdentity remote_identity(remote_cert);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001397
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001398 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1399 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001400}
1401
zhihuang6ba3b192016-05-13 11:46:35 -07001402// This test verifies that the audio/video related stats which are -1 initially
1403// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001404TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001405 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001406 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001407 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001408 }
zhihuang6ba3b192016-05-13 11:46:35 -07001409
Steve Anton3871f6f2018-01-26 10:25:53 -08001410 auto pc = CreatePeerConnection();
1411 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001412
1413 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 11:34:10 -08001414 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 11:46:35 -07001415 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1416 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1417 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001418 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001419 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001420 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001421 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001422 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001423
1424 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001425 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001426 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 11:46:35 -07001427 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1428 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001429 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001430 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001431 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001432 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001433 }
zhihuang6ba3b192016-05-13 11:46:35 -07001434
Steve Anton3871f6f2018-01-26 10:25:53 -08001435 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001436 voice_sender_info.add_ssrc(kSsrcOfTrack);
1437 // These values are set to -1 initially in audio_send_stream.
1438 // The voice_sender_info will read the values from audio_send_stream.
1439 voice_sender_info.rtt_ms = -1;
1440 voice_sender_info.packets_lost = -1;
1441 voice_sender_info.jitter_ms = -1;
1442
1443 // Some of the contents in |voice_sender_info| needs to be updated from the
1444 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001445 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1446 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001447
Steve Anton3871f6f2018-01-26 10:25:53 -08001448 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001449 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1450 voice_receiver_info.capture_start_ntp_time_ms = -1;
1451 voice_receiver_info.audio_level = -1;
1452
1453 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001454 VoiceMediaInfo voice_info;
1455 voice_info.senders.push_back(voice_sender_info);
1456 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001457
Steve Anton5b387312018-02-02 16:00:20 -08001458 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1459 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001460
Steve Anton3871f6f2018-01-26 10:25:53 -08001461 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001462
1463 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001464 StatsReports reports;
1465 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001466 const StatsReport* report =
1467 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001468 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001469 // The -1 will not be added to the stats report.
1470 std::string value_in_report;
1471 EXPECT_FALSE(
1472 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1473 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1474 &value_in_report));
1475 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1476 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001477 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1478 &value_in_report));
1479 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1480 &value_in_report));
1481
1482 // Get stats for the remote track.
1483 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001484 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001485 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001486 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001487 EXPECT_FALSE(GetValue(report,
1488 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1489 &value_in_report));
1490 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1491 &value_in_report));
1492}
1493
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001494// This test verifies that a local stats object can get statistics via
1495// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001496TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001497 auto pc = CreatePeerConnection();
1498 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001499
Steve Anton3871f6f2018-01-26 10:25:53 -08001500 AddOutgoingAudioTrack(pc, stats.get());
1501 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001502
Steve Anton3871f6f2018-01-26 10:25:53 -08001503 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001504 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001505 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1506 VoiceMediaInfo voice_info;
1507 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001508
1509 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1510 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001511
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001512 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001513 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001514
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001515 // Verify that there is no remote report for the local audio track because
1516 // we did not set it up.
Yves Gerey665174f2018-06-19 15:03:05 +02001517 const StatsReport* remote_report =
1518 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001519 EXPECT_TRUE(remote_report == NULL);
1520}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001521
1522// This test verifies that audio receive streams populate stats reports
1523// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001524TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001525 auto pc = CreatePeerConnection();
1526 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001527
Steve Anton3871f6f2018-01-26 10:25:53 -08001528 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001529
Steve Anton3871f6f2018-01-26 10:25:53 -08001530 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001531 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001532 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001533 VoiceMediaInfo voice_info;
1534 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001535
1536 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1537 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001538
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001539 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001540 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001541}
1542
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001543// This test verifies that a local stats object won't update its statistics
1544// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001545TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001546 auto pc = CreatePeerConnection();
1547 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001548
Steve Anton3871f6f2018-01-26 10:25:53 -08001549 AddOutgoingAudioTrack(pc, stats.get());
1550 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001551
Steve Anton3871f6f2018-01-26 10:25:53 -08001552 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001553 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001554 VoiceMediaInfo voice_info;
1555 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001556
Steve Anton5b387312018-02-02 16:00:20 -08001557 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1558 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001559
Steve Anton3871f6f2018-01-26 10:25:53 -08001560 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001561
Steve Anton3871f6f2018-01-26 10:25:53 -08001562 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1563 StatsReports reports;
1564 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001565
1566 // The report will exist since we don't remove them in RemoveStream().
Yves Gerey665174f2018-06-19 15:03:05 +02001567 const StatsReport* report =
1568 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001569 ASSERT_TRUE(report);
1570 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001571 std::string track_id =
1572 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001573 EXPECT_EQ(kLocalTrackId, track_id);
Yves Gerey665174f2018-06-19 15:03:05 +02001574 std::string ssrc_id =
1575 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001576 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001577
1578 // Verifies the values in the track report, no value will be changed by the
1579 // AudioTrackInterface::GetSignalValue() and
1580 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1581 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1582}
1583
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001584// This test verifies that when ongoing and incoming audio tracks are using
1585// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001586TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001587 auto pc = CreatePeerConnection();
1588 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001589
1590 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001591 AddOutgoingAudioTrack(pc, stats.get());
1592 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001593
1594 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001595 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001596 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001597 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1598 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001599 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001600 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001601 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001602
Steve Anton3871f6f2018-01-26 10:25:53 -08001603 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001604 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001605 // Some of the contents in |voice_sender_info| needs to be updated from the
1606 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001607 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1608 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001609
Steve Anton3871f6f2018-01-26 10:25:53 -08001610 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001611 InitVoiceReceiverInfo(&voice_receiver_info);
1612
1613 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001614 VoiceMediaInfo voice_info;
1615 voice_info.senders.push_back(voice_sender_info);
1616 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001617
Steve Anton3871f6f2018-01-26 10:25:53 -08001618 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001619 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1620 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001621
Steve Anton3871f6f2018-01-26 10:25:53 -08001622 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001623
1624 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001625 StatsReports reports; // returned values.
1626 stats->GetStats(audio_track_.get(), &reports);
1627
Yves Gerey665174f2018-06-19 15:03:05 +02001628 const StatsReport* track_report =
1629 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001630 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001631 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001632 std::string track_id =
1633 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001634 EXPECT_EQ(kLocalTrackId, track_id);
1635 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1636
1637 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001638 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001639 stats->GetStats(remote_track.get(), &reports);
Yves Gerey665174f2018-06-19 15:03:05 +02001640 track_report =
1641 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001642 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001643 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001644 track_id =
1645 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001646 EXPECT_EQ(kRemoteTrackId, track_id);
1647 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1648}
1649
xians@webrtc.org01bda202014-07-09 07:38:38 +00001650// This test verifies that when two outgoing audio tracks are using the same
1651// ssrc at different times, they populate stats reports correctly.
1652// TODO(xians): Figure out if it is possible to encapsulate the setup and
1653// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001654TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001655 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001656 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001657 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001658 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001659
Steve Anton3871f6f2018-01-26 10:25:53 -08001660 auto pc = CreatePeerConnection();
1661 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001662
1663 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001664 AddOutgoingAudioTrack(pc, stats.get());
1665 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001666
Steve Anton3871f6f2018-01-26 10:25:53 -08001667 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001668 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001669 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001670 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001671 VoiceMediaInfo voice_info;
1672 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001673
1674 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1675 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001676
xians@webrtc.org01bda202014-07-09 07:38:38 +00001677 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001678 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001679
1680 // Remove the previous audio track from the stream.
1681 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001682 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001683
1684 // Create a new audio track and adds it to the stream and stats.
1685 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001686 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1687 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001688 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001689 stream_->AddTrack(new_audio_track);
1690
Steve Anton3871f6f2018-01-26 10:25:53 -08001691 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1692 stats->ClearUpdateStatsCacheForTest();
1693
1694 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001695 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001696 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1697 false);
1698 VoiceMediaInfo new_voice_info;
1699 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001700 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001701
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001702 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001703 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001704}
1705
sakal43536c32016-10-24 01:46:43 -07001706// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001707TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001708 auto pc = CreatePeerConnection();
1709 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001710
Steve Anton3871f6f2018-01-26 10:25:53 -08001711 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001712
Steve Anton3871f6f2018-01-26 10:25:53 -08001713 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001714 video_sender_info.add_ssrc(1234);
1715 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001716 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001717 VideoMediaInfo video_info;
1718 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001719
1720 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1721 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001722
Steve Anton3871f6f2018-01-26 10:25:53 -08001723 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1724 StatsReports reports;
1725 stats->GetStats(nullptr, &reports);
1726
sakal43536c32016-10-24 01:46:43 -07001727 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1728 ExtractSsrcStatsValue(reports,
1729 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001730 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1731 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001732}
1733
sakale5ba44e2016-10-26 07:09:24 -07001734// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001735TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1736 auto pc = CreatePeerConnection();
1737 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001738
Steve Anton3871f6f2018-01-26 10:25:53 -08001739 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001740
Steve Anton3871f6f2018-01-26 10:25:53 -08001741 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001742 video_receiver_info.add_ssrc(1234);
1743 video_receiver_info.frames_decoded = 10;
Artem Titov8a3ab0e2018-07-27 14:52:57 +00001744 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001745 VideoMediaInfo video_info;
1746 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001747
1748 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1749 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001750
Steve Anton3871f6f2018-01-26 10:25:53 -08001751 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1752 StatsReports reports;
1753 stats->GetStats(nullptr, &reports);
1754
sakale5ba44e2016-10-26 07:09:24 -07001755 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1756 ExtractSsrcStatsValue(reports,
1757 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001758 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1759 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001760}
1761
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001762INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1763
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001764} // namespace webrtc