blob: ffb0a5a127a207283b141fecc1c449ba88a6048b [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"
24#include "rtc_base/base64.h"
25#include "rtc_base/fakesslidentity.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.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000197const StatsReport* FindNthReportByType(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000198 const StatsReports& reports, const StatsReport::StatsType& type, int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000200 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 n--;
202 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000203 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 }
205 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000206 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207}
208
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000209const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000210 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000211 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000212 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000213 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000215 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216}
217
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100218std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000219 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000220 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221}
222
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100223std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000224 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000226 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(
231 rtc::kPemTypeCertificate,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000232 reinterpret_cast<const unsigned char*>(der.c_str()),
233 der.length());
234}
235
236std::vector<std::string> DersToPems(
237 const std::vector<std::string>& ders) {
238 std::vector<std::string> pems(ders.size());
239 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
240 return pems;
241}
242
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000243void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000244 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000245 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000246 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000247 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000248 size_t i = 0;
249 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000250 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000251 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000252
wu@webrtc.org4551b792013-10-09 15:37:36 +0000253 std::string der_base64;
254 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000255 report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000256 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000257 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000258
259 std::string fingerprint_algorithm;
260 EXPECT_TRUE(GetValue(
261 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000262 StatsReport::kStatsValueNameFingerprintAlgorithm,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000263 &fingerprint_algorithm));
264 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000265 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000266 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
267
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000268 std::string fingerprint;
269 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
270 &fingerprint));
271 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000272
wu@webrtc.org4551b792013-10-09 15:37:36 +0000273 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000274 std::string issuer_id;
275 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId,
276 &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000277 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000278 }
279
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000280 cert_id = IdFromCertIdString(issuer_id);
281 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000282 }
283 EXPECT_EQ(ders.size(), i);
284}
285
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000286void VerifyVoiceReceiverInfoReport(
287 const StatsReport* report,
288 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000289 std::string value_in_report;
290 EXPECT_TRUE(GetValue(
291 report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000292 EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000293 EXPECT_TRUE(GetValue(
294 report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200295 EXPECT_EQ(rtc::ToString<int64_t>(info.bytes_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000296 EXPECT_TRUE(GetValue(
297 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000298 EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000299 EXPECT_TRUE(GetValue(
300 report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000301 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000302 EXPECT_TRUE(GetValue(
303 report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
304 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000305 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000306 value_in_report);
307 EXPECT_TRUE(GetValue(
308 report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000309 EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000310 EXPECT_TRUE(GetValue(
311 report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000312 EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000313 EXPECT_TRUE(GetValue(
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000314 report, StatsReport::kStatsValueNameSpeechExpandRate, &value_in_report));
315 EXPECT_EQ(rtc::ToString<float>(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200316 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
317 &value_in_report));
318 EXPECT_EQ(rtc::ToString<float>(info.accelerate_rate), value_in_report);
319 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
320 &value_in_report));
321 EXPECT_EQ(rtc::ToString<float>(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000322 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
323 &value_in_report));
324 EXPECT_EQ(rtc::ToString<float>(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200325 EXPECT_TRUE(GetValue(report,
326 StatsReport::kStatsValueNameSecondaryDiscardedRate,
327 &value_in_report));
328 EXPECT_EQ(rtc::ToString<float>(info.secondary_discarded_rate),
329 value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000330 EXPECT_TRUE(GetValue(
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000331 report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000332 EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000333 EXPECT_TRUE(GetValue(
334 report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000335 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000336 value_in_report);
337 EXPECT_TRUE(GetValue(
338 report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000339 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000340 value_in_report);
341 EXPECT_TRUE(GetValue(
342 report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000343 EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000344 EXPECT_TRUE(GetValue(
345 report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000346 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000347 EXPECT_TRUE(GetValue(
348 report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000349 EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000350 EXPECT_TRUE(GetValue(
351 report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000352 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700353 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
354 &value_in_report));
355 EXPECT_EQ(rtc::ToString<int>(info.decoding_muted_output), value_in_report);
356 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
357 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000358}
359
360
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000361void VerifyVoiceSenderInfoReport(const StatsReport* report,
362 const cricket::VoiceSenderInfo& sinfo) {
363 std::string value_in_report;
364 EXPECT_TRUE(GetValue(
365 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
366 EXPECT_EQ(sinfo.codec_name, value_in_report);
367 EXPECT_TRUE(GetValue(
368 report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200369 EXPECT_EQ(rtc::ToString<int64_t>(sinfo.bytes_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000370 EXPECT_TRUE(GetValue(
371 report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000372 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000373 EXPECT_TRUE(GetValue(
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000374 report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000375 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000376 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000377 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000378 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000379 EXPECT_TRUE(GetValue(
380 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000381 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000382 EXPECT_TRUE(GetValue(
383 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000384 EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100385 if (sinfo.apm_statistics.delay_median_ms) {
386 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
387 &value_in_report));
388 EXPECT_EQ(rtc::ToString<int>(*sinfo.apm_statistics.delay_median_ms),
389 value_in_report);
390 } else {
391 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
392 &value_in_report));
393 }
394 if (sinfo.apm_statistics.delay_standard_deviation_ms) {
395 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
396 &value_in_report));
397 EXPECT_EQ(
398 rtc::ToString<int>(*sinfo.apm_statistics.delay_standard_deviation_ms),
399 value_in_report);
400 } else {
401 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
402 &value_in_report));
403 }
404 if (sinfo.apm_statistics.echo_return_loss) {
405 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
406 &value_in_report));
407 EXPECT_EQ(rtc::ToString<int>(*sinfo.apm_statistics.echo_return_loss),
408 value_in_report);
409 } else {
410 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
411 &value_in_report));
412 }
413 if (sinfo.apm_statistics.echo_return_loss_enhancement) {
414 EXPECT_TRUE(GetValue(report,
415 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
416 &value_in_report));
417 EXPECT_EQ(
418 rtc::ToString<int>(*sinfo.apm_statistics.echo_return_loss_enhancement),
419 value_in_report);
420 } else {
421 EXPECT_FALSE(GetValue(report,
422 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
423 &value_in_report));
424 }
425 if (sinfo.apm_statistics.residual_echo_likelihood) {
426 EXPECT_TRUE(GetValue(report,
427 StatsReport::kStatsValueNameResidualEchoLikelihood,
428 &value_in_report));
429 EXPECT_EQ(
430 rtc::ToString<float>(*sinfo.apm_statistics.residual_echo_likelihood),
431 value_in_report);
432 } else {
433 EXPECT_FALSE(GetValue(report,
434 StatsReport::kStatsValueNameResidualEchoLikelihood,
435 &value_in_report));
436 }
437 if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) {
438 EXPECT_TRUE(GetValue(
439 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
440 &value_in_report));
441 EXPECT_EQ(rtc::ToString<float>(
442 *sinfo.apm_statistics.residual_echo_likelihood_recent_max),
443 value_in_report);
444 } else {
445 EXPECT_FALSE(GetValue(
446 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
447 &value_in_report));
448 }
ivoc8c63a822016-10-21 04:10:03 -0700449 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
450 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000451 EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000452 EXPECT_TRUE(GetValue(
453 report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
454 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
455 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700456 EXPECT_TRUE(GetValue(report,
457 StatsReport::kStatsValueNameAnaBitrateActionCounter,
458 &value_in_report));
459 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
460 EXPECT_EQ(
461 rtc::ToString<uint32_t>(*sinfo.ana_statistics.bitrate_action_counter),
462 value_in_report);
463 EXPECT_TRUE(GetValue(report,
464 StatsReport::kStatsValueNameAnaChannelActionCounter,
465 &value_in_report));
466 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
467 EXPECT_EQ(
468 rtc::ToString<uint32_t>(*sinfo.ana_statistics.channel_action_counter),
469 value_in_report);
470 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
471 &value_in_report));
472 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
473 EXPECT_EQ(rtc::ToString<uint32_t>(*sinfo.ana_statistics.dtx_action_counter),
474 value_in_report);
475 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter,
476 &value_in_report));
477 ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter);
478 EXPECT_EQ(rtc::ToString<uint32_t>(*sinfo.ana_statistics.fec_action_counter),
479 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700480 EXPECT_TRUE(GetValue(
481 report, StatsReport::kStatsValueNameAnaFrameLengthIncreaseCounter,
482 &value_in_report));
483 ASSERT_TRUE(sinfo.ana_statistics.frame_length_increase_counter);
ivoce1198e02017-09-08 08:13:19 -0700484 EXPECT_EQ(rtc::ToString<uint32_t>(
ivoc0d0b9122017-09-08 13:24:21 -0700485 *sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 08:13:19 -0700486 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700487 EXPECT_TRUE(GetValue(
488 report, StatsReport::kStatsValueNameAnaFrameLengthDecreaseCounter,
489 &value_in_report));
490 ASSERT_TRUE(sinfo.ana_statistics.frame_length_decrease_counter);
491 EXPECT_EQ(rtc::ToString<uint32_t>(
492 *sinfo.ana_statistics.frame_length_decrease_counter),
493 value_in_report);
494 EXPECT_TRUE(GetValue(report,
495 StatsReport::kStatsValueNameAnaUplinkPacketLossFraction,
496 &value_in_report));
497 ASSERT_TRUE(sinfo.ana_statistics.uplink_packet_loss_fraction);
498 EXPECT_EQ(
499 rtc::ToString<float>(*sinfo.ana_statistics.uplink_packet_loss_fraction),
500 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000501}
502
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000503// Helper methods to avoid duplication of code.
504void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
505 voice_sender_info->add_ssrc(kSsrcOfTrack);
506 voice_sender_info->codec_name = "fake_codec";
507 voice_sender_info->bytes_sent = 100;
508 voice_sender_info->packets_sent = 101;
509 voice_sender_info->rtt_ms = 102;
510 voice_sender_info->fraction_lost = 103;
511 voice_sender_info->jitter_ms = 104;
512 voice_sender_info->packets_lost = 105;
513 voice_sender_info->ext_seqnum = 106;
514 voice_sender_info->audio_level = 107;
515 voice_sender_info->echo_return_loss = 108;
516 voice_sender_info->echo_return_loss_enhancement = 109;
517 voice_sender_info->echo_delay_median_ms = 110;
518 voice_sender_info->echo_delay_std_ms = 111;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000519 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d46092017-11-24 17:29:59 +0100520 voice_sender_info->ana_statistics.bitrate_action_counter = 112;
521 voice_sender_info->ana_statistics.channel_action_counter = 113;
522 voice_sender_info->ana_statistics.dtx_action_counter = 114;
523 voice_sender_info->ana_statistics.fec_action_counter = 115;
524 voice_sender_info->ana_statistics.frame_length_increase_counter = 116;
525 voice_sender_info->ana_statistics.frame_length_decrease_counter = 117;
526 voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000527}
528
529void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700530 AudioTrackInterface* audio_track,
Ivo Creusen56d46092017-11-24 17:29:59 +0100531 cricket::VoiceSenderInfo* voice_sender_info,
532 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000533 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 10:25:53 -0800534 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
535 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000536 voice_sender_info->typing_noise_detected =
537 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d46092017-11-24 17:29:59 +0100538 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000539}
540
541void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
542 voice_receiver_info->add_ssrc(kSsrcOfTrack);
543 voice_receiver_info->bytes_rcvd = 110;
544 voice_receiver_info->packets_rcvd = 111;
545 voice_receiver_info->packets_lost = 112;
546 voice_receiver_info->fraction_lost = 113;
547 voice_receiver_info->packets_lost = 114;
548 voice_receiver_info->ext_seqnum = 115;
549 voice_receiver_info->jitter_ms = 116;
550 voice_receiver_info->jitter_buffer_ms = 117;
551 voice_receiver_info->jitter_buffer_preferred_ms = 118;
552 voice_receiver_info->delay_estimate_ms = 119;
553 voice_receiver_info->audio_level = 120;
554 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000555 voice_receiver_info->speech_expand_rate = 122;
556 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200557 voice_receiver_info->accelerate_rate = 124;
558 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200559 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000560}
561
Steve Anton3871f6f2018-01-26 10:25:53 -0800562class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000563 public:
Steve Anton3871f6f2018-01-26 10:25:53 -0800564 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 11:33:11 -0700565 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000566
567 double GetTimeNow() override {
568 return time_now_;
569 }
570
571 private:
572 double time_now_;
573};
574
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575class StatsCollectorTest : public testing::Test {
576 protected:
Steve Anton3871f6f2018-01-26 10:25:53 -0800577 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
578 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 }
580
Steve Anton3871f6f2018-01-26 10:25:53 -0800581 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
582 PeerConnectionInternal* pc) {
583 return rtc::MakeUnique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000584 }
585
Steve Anton3871f6f2018-01-26 10:25:53 -0800586 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
587 StatsCollectorForTest* stats,
588 const VoiceMediaInfo& voice_info,
589 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38 +0000590 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000591 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 10:25:53 -0800592 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000593
594 // Verify the existence of the track report.
595 const StatsReport* report = FindNthReportByType(
596 *reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800597 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 15:06:43 -0700598 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000599 std::string track_id = ExtractSsrcStatsValue(
600 *reports, StatsReport::kStatsValueNameTrackId);
601 EXPECT_EQ(audio_track->id(), track_id);
602 std::string ssrc_id = ExtractSsrcStatsValue(
603 *reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200604 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000605
fippobec70ab2016-01-28 01:27:15 -0800606 std::string media_type = ExtractSsrcStatsValue(*reports,
607 StatsReport::kStatsValueNameMediaType);
608 EXPECT_EQ("audio", media_type);
609
xians@webrtc.org01bda202014-07-09 07:38:38 +0000610 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 10:25:53 -0800611 if (!voice_info.senders.empty()) {
612 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000613 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800614 if (!voice_info.receivers.empty()) {
615 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000616 }
617
618 // Verify we get the same result by passing a track to GetStats().
619 StatsReports track_reports; // returned values.
620 stats->GetStats(audio_track, &track_reports);
621 const StatsReport* track_report = FindNthReportByType(
622 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800623 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700624 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000625 track_id = ExtractSsrcStatsValue(track_reports,
626 StatsReport::kStatsValueNameTrackId);
627 EXPECT_EQ(audio_track->id(), track_id);
628 ssrc_id = ExtractSsrcStatsValue(track_reports,
629 StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200630 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 10:25:53 -0800631 if (!voice_info.senders.empty()) {
632 VerifyVoiceSenderInfoReport(track_report, voice_info.senders[0]);
633 }
634 if (!voice_info.receivers.empty()) {
635 VerifyVoiceReceiverInfoReport(track_report, voice_info.receivers[0]);
636 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000637 }
638
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800639 void TestCertificateReports(const rtc::FakeSSLIdentity& local_identity,
640 const std::vector<std::string>& local_ders,
641 const rtc::FakeSSLIdentity& remote_identity,
642 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800643 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000644
Steve Anton3871f6f2018-01-26 10:25:53 -0800645 auto pc = CreatePeerConnection();
646 auto stats = CreateStatsCollector(pc);
647
Steve Anton5b387312018-02-02 16:00:20 -0800648 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000649
650 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800651 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000652 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800653 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700654 channel_stats.ssl_cipher_suite =
655 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800656 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000657
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800658 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 10:12:24 +0200659 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800660 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800661 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 10:25:53 -0800662 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800663 pc->SetRemoteCertChain(kTransportName,
664 remote_identity.cert_chain().UniqueCopy());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000665
Steve Anton3871f6f2018-01-26 10:25:53 -0800666 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000667
Steve Anton3871f6f2018-01-26 10:25:53 -0800668 StatsReports reports;
669 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000670
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000671 const StatsReport* channel_report = FindNthReportByType(
672 reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800673 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000674
675 // Check local certificate chain.
676 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000677 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000678 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000679 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000680 if (local_ders.size() > 0) {
681 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000682 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
683 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000684 } else {
685 EXPECT_EQ(kNotFound, local_certificate_id);
686 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000687
688 // Check remote certificate chain.
689 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000690 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000691 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000692 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000693 if (remote_ders.size() > 0) {
694 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000695 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
696 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000697 } else {
698 EXPECT_EQ(kNotFound, remote_certificate_id);
699 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000700
701 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800702 std::string dtls_cipher_suite =
703 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
704 StatsReport::kStatsValueNameDtlsCipher);
705 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700706 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800707 dtls_cipher_suite);
708 std::string srtp_crypto_suite =
709 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
710 StatsReport::kStatsValueNameSrtpCipher);
711 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
712 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000713 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100714};
715
716class StatsCollectorTrackTest : public StatsCollectorTest,
717 public ::testing::WithParamInterface<bool> {
718 public:
719 // Adds a outgoing video track with a given SSRC into the stats.
720 // If GetParam() returns true, the track is also inserted into the local
721 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800722 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
723 StatsCollectorForTest* stats) {
724 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
725 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100726 if (GetParam()) {
727 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800728 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100729 stream_->AddTrack(track_);
730 stats->AddStream(stream_);
731 } else {
732 stats->AddTrack(track_);
733 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800734 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100735 }
736
737 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800738 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
739 StatsCollectorForTest* stats) {
740 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
741 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100742 if (GetParam()) {
Seth Hampson845e8782018-03-02 11:34:10 -0800743 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100744 stream_->AddTrack(track_);
745 stats->AddStream(stream_);
746 } else {
747 stats->AddTrack(track_);
748 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800749 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100750 }
751
752 // Adds a outgoing audio track with a given SSRC into the stats,
753 // and register it into the stats object.
754 // If GetParam() returns true, the track is also inserted into the local
755 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800756 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
757 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100758 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
759 if (GetParam()) {
760 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800761 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100762 stream_->AddTrack(audio_track_);
763 stats->AddStream(stream_);
764 } else {
765 stats->AddTrack(audio_track_);
766 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800767 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100768 }
769
770 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800771 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
772 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100773 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
774 if (GetParam()) {
775 if (stream_ == NULL)
Seth Hampson845e8782018-03-02 11:34:10 -0800776 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100777 stream_->AddTrack(audio_track_);
778 stats->AddStream(stream_);
779 } else {
780 stats->AddTrack(audio_track_);
781 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800782 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100783 }
784
Steve Anton3871f6f2018-01-26 10:25:53 -0800785 rtc::scoped_refptr<MediaStream> stream_;
786 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000787 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788};
789
zhihuang6ba3b192016-05-13 11:46:35 -0700790TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800791 auto pc = CreatePeerConnection();
792 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -0700793
Steve Anton3871f6f2018-01-26 10:25:53 -0800794 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 11:46:35 -0700795
Steve Anton3871f6f2018-01-26 10:25:53 -0800796 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -0700797 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800798 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 11:46:35 -0700799
800 const StatsReport* report =
801 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
802
803 std::string value_in_report;
804 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
805 &value_in_report));
806}
807
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000808// Verify that ExtractDataInfo populates reports.
809TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800810 const std::string kDataChannelLabel = "hacks";
811 constexpr int kDataChannelId = 31337;
812 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000813 DataChannelInterface::DataState::kConnecting);
814
Steve Anton3871f6f2018-01-26 10:25:53 -0800815 auto pc = CreatePeerConnection();
816 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000817
Steve Anton3871f6f2018-01-26 10:25:53 -0800818 InternalDataChannelInit init;
819 init.id = kDataChannelId;
820 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000821
Steve Anton3871f6f2018-01-26 10:25:53 -0800822 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000823 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800824 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000825
826 const StatsReport* report =
827 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
828
Steve Anton3871f6f2018-01-26 10:25:53 -0800829 StatsReport::Id report_id = StatsReport::NewTypedIntId(
830 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000831
Steve Anton3871f6f2018-01-26 10:25:53 -0800832 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000833
Steve Anton3871f6f2018-01-26 10:25:53 -0800834 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
835 EXPECT_EQ(kDataChannelLabel,
836 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
837 StatsReport::kStatsValueNameLabel));
838 EXPECT_EQ(rtc::ToString<int64_t>(kDataChannelId),
Peter Boström0c4e06b2015-10-07 12:23:21 +0200839 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000840 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 10:25:53 -0800841 EXPECT_EQ(kConnectingString,
842 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
843 StatsReport::kStatsValueNameState));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000844 EXPECT_EQ("", ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
845 reports,
846 StatsReport::kStatsValueNameProtocol));
847}
848
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100850TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 10:25:53 -0800852 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853
Steve Anton3871f6f2018-01-26 10:25:53 -0800854 auto pc = CreatePeerConnection();
855 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856
Steve Anton3871f6f2018-01-26 10:25:53 -0800857 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000858 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000859 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800860 VideoMediaInfo video_info;
861 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800862
863 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
864 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000865
Steve Anton3871f6f2018-01-26 10:25:53 -0800866 AddOutgoingVideoTrack(pc, stats.get());
867
868 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
869 StatsReports reports;
870 stats->GetStats(nullptr, &reports);
871
872 EXPECT_EQ(
873 rtc::ToString(kBytesSent),
874 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875}
876
Alex Narest42308f62017-06-19 17:58:12 +0200877// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100878TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 17:58:12 +0200879 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
880 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800881 constexpr int64_t kBytesSent = 12345678901234LL;
882 constexpr int kSendBandwidth = 1234567;
883 constexpr int kRecvBandwidth = 12345678;
884 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 17:58:12 +0200885
Steve Anton3871f6f2018-01-26 10:25:53 -0800886 auto pc = CreatePeerConnection();
887 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 17:58:12 +0200888
Steve Anton3871f6f2018-01-26 10:25:53 -0800889 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 17:58:12 +0200890 voice_sender_info.add_ssrc(1234);
891 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800892 VoiceMediaInfo voice_info;
893 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800894
895 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
896 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 17:58:12 +0200897
Steve Anton3871f6f2018-01-26 10:25:53 -0800898 AddOutgoingAudioTrack(pc, stats.get());
899
900 Call::Stats call_stats;
Alex Narest42308f62017-06-19 17:58:12 +0200901 call_stats.send_bandwidth_bps = kSendBandwidth;
902 call_stats.recv_bandwidth_bps = kRecvBandwidth;
903 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800904 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 17:58:12 +0200905
Steve Anton3871f6f2018-01-26 10:25:53 -0800906 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
907 StatsReports reports;
908 stats->GetStats(nullptr, &reports);
909
910 EXPECT_EQ(
911 rtc::ToString(kBytesSent),
912 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
913 EXPECT_EQ(rtc::ToString(kSendBandwidth),
914 ExtractBweStatsValue(
915 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
916 EXPECT_EQ(
917 rtc::ToString(kRecvBandwidth),
918 ExtractBweStatsValue(
919 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
920 EXPECT_EQ(
921 rtc::ToString(kPacerDelay),
922 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
Alex Narest42308f62017-06-19 17:58:12 +0200923}
924
925// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100926TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
928 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800929 constexpr int64_t kBytesSent = 12345678901234LL;
930 constexpr int kSendBandwidth = 1234567;
931 constexpr int kRecvBandwidth = 12345678;
932 constexpr int kPacerDelay = 123;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
Steve Anton3871f6f2018-01-26 10:25:53 -0800934 auto pc = CreatePeerConnection();
935 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936
Steve Anton3871f6f2018-01-26 10:25:53 -0800937 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000938 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800940 VideoMediaInfo video_info;
941 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800942
943 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
944 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945
Steve Anton3871f6f2018-01-26 10:25:53 -0800946 AddOutgoingVideoTrack(pc, stats.get());
947
948 Call::Stats call_stats;
stefanf79ade12017-06-02 06:44:03 -0700949 call_stats.send_bandwidth_bps = kSendBandwidth;
950 call_stats.recv_bandwidth_bps = kRecvBandwidth;
951 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800952 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000953
Steve Anton3871f6f2018-01-26 10:25:53 -0800954 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
955 StatsReports reports;
956 stats->GetStats(nullptr, &reports);
957
958 EXPECT_EQ(
959 rtc::ToString(kBytesSent),
960 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
961 EXPECT_EQ(rtc::ToString(kSendBandwidth),
962 ExtractBweStatsValue(
963 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
964 EXPECT_EQ(
965 rtc::ToString(kRecvBandwidth),
966 ExtractBweStatsValue(
967 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
968 EXPECT_EQ(
969 rtc::ToString(kPacerDelay),
970 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971}
972
973// This test verifies that an object of type "googSession" always
974// exists in the returned stats.
975TEST_F(StatsCollectorTest, SessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800976 auto pc = CreatePeerConnection();
977 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000978
Steve Anton3871f6f2018-01-26 10:25:53 -0800979 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
980 StatsReports reports;
981 stats->GetStats(nullptr, &reports);
982
983 EXPECT_TRUE(
984 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985}
986
987// This test verifies that only one object of type "googSession" exists
988// in the returned stats.
989TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800990 auto pc = CreatePeerConnection();
991 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000992
Steve Anton3871f6f2018-01-26 10:25:53 -0800993 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
994 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
995 StatsReports reports;
996 stats->GetStats(nullptr, &reports);
997
998 EXPECT_TRUE(
999 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
1000 EXPECT_FALSE(
1001 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002}
1003
1004// This test verifies that the empty track report exists in the returned stats
1005// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001006TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001007 auto pc = CreatePeerConnection();
1008 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001009
Steve Anton5b387312018-02-02 16:00:20 -08001010 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001011 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001012
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001013 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001014 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001015 stats->GetStats(nullptr, &reports);
1016 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001017 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -07001018 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019
1020 std::string trackValue =
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001021 ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001023 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001024 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025}
1026
1027// This test verifies that the empty track report exists in the returned stats
1028// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001029TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001030 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001031
Steve Anton3871f6f2018-01-26 10:25:53 -08001032 auto pc = CreatePeerConnection();
1033 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001034
Steve Anton3871f6f2018-01-26 10:25:53 -08001035 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001036 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001037 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001038 VideoMediaInfo video_info;
1039 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001040
1041 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1042 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043
Steve Anton3871f6f2018-01-26 10:25:53 -08001044 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045
Steve Anton3871f6f2018-01-26 10:25:53 -08001046 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001047 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001048 stats->GetStats(nullptr, &reports);
1049
wu@webrtc.org97077a32013-10-25 21:18:33 +00001050 // |reports| should contain at least one session report, one track report,
1051 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001052 EXPECT_LE(3u, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001053 const StatsReport* track_report = FindNthReportByType(
1054 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001055 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001056
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001057 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001058 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001059 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001060 // |reports| should contain at least one session report, one track report,
1061 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001062 EXPECT_LE(3u, reports.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001063 track_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001064 reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001065 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001066 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067
1068 std::string ssrc_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001069 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001070 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071
1072 std::string track_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001073 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001074 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001075
1076 std::string media_type = ExtractSsrcStatsValue(reports,
1077 StatsReport::kStatsValueNameMediaType);
1078 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001079}
1080
1081// This test verifies that an SSRC object has the identifier of a Transport
1082// stats object, and that this transport stats object exists in stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001083TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001084 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001085
Steve Anton3871f6f2018-01-26 10:25:53 -08001086 auto pc = CreatePeerConnection();
1087 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001088
Steve Anton3871f6f2018-01-26 10:25:53 -08001089 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001090 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001091 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001092 VideoMediaInfo video_info;
1093 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001094
1095 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1096 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001097
Steve Anton3871f6f2018-01-26 10:25:53 -08001098 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001099
Steve Anton3871f6f2018-01-26 10:25:53 -08001100 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001101 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001102 stats->GetStats(nullptr, &reports);
1103
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001104 std::string transport_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001105 StatsReport::kStatsReportTypeSsrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001106 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001107 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001108 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001109
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001110 // Transport id component ID will always be 1.
1111 // This has assumptions about how the ID is constructed. As is, this is
1112 // OK since this is for testing purposes only, but if we ever need this
1113 // in production, we should add a generic method that does this.
1114 size_t index = transport_id.find('-');
1115 ASSERT_NE(std::string::npos, index);
1116 std::string content = transport_id.substr(index + 1);
1117 index = content.rfind('-');
1118 ASSERT_NE(std::string::npos, index);
1119 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001120 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001121 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001122 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001123 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001124}
1125
wu@webrtc.org97077a32013-10-25 21:18:33 +00001126// This test verifies that a remote stats object will not be created for
1127// an outgoing SSRC where remote stats are not returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001128TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001129 auto pc = CreatePeerConnection();
1130 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001131
Steve Anton5b387312018-02-02 16:00:20 -08001132 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001133 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001134
Steve Anton3871f6f2018-01-26 10:25:53 -08001135 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001136 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001137 stats->GetStats(nullptr, &reports);
1138
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001139 const StatsReport* remote_report = FindNthReportByType(reports,
1140 StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001141 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001142}
1143
1144// This test verifies that a remote stats object will be created for
1145// an outgoing SSRC where stats are returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001146TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001147 auto pc = CreatePeerConnection();
1148 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001149
Steve Anton3871f6f2018-01-26 10:25:53 -08001150 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001151 remote_ssrc_stats.timestamp = 12345.678;
1152 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 10:25:53 -08001153 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001154 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001155 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 10:25:53 -08001156 VideoMediaInfo video_info;
1157 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001158
1159 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1160 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001161
Steve Anton3871f6f2018-01-26 10:25:53 -08001162 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001163
Steve Anton3871f6f2018-01-26 10:25:53 -08001164 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001165 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001166 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001167
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001168 const StatsReport* remote_report = FindNthReportByType(reports,
1169 StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001170 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001171 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001172}
1173
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001174// This test verifies that the empty track report exists in the returned stats
1175// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001176TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001177 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001178
Steve Anton3871f6f2018-01-26 10:25:53 -08001179 auto pc = CreatePeerConnection();
1180 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001181
Steve Anton3871f6f2018-01-26 10:25:53 -08001182 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001183 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001184 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 10:25:53 -08001185 VideoMediaInfo video_info;
1186 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001187
1188 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1189 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001190
Steve Anton3871f6f2018-01-26 10:25:53 -08001191 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001192
Steve Anton3871f6f2018-01-26 10:25:53 -08001193 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001194 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001195 stats->GetStats(nullptr, &reports);
1196
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001197 // |reports| should contain at least one session report, one track report,
1198 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001199 EXPECT_LE(3u, reports.size());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001200 const StatsReport* track_report = FindNthReportByType(
1201 reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001202 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001203 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001204
1205 std::string ssrc_id = ExtractSsrcStatsValue(
1206 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001207 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001208
1209 std::string track_id = ExtractSsrcStatsValue(
1210 reports, StatsReport::kStatsValueNameTrackId);
1211 EXPECT_EQ(kRemoteTrackId, track_id);
1212}
1213
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001214// This test verifies the Ice Candidate report should contain the correct
1215// information from local/remote candidates.
1216TEST_F(StatsCollectorTest, IceCandidateReport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001217 const std::string kTransportName = "transport";
1218 const rtc::AdapterType kNetworkType = rtc::ADAPTER_TYPE_ETHERNET;
1219 constexpr uint32_t kPriority = 1000;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001220
Steve Anton3871f6f2018-01-26 10:25:53 -08001221 constexpr int kLocalPort = 2000;
1222 const std::string kLocalIp = "192.168.0.1";
1223 const rtc::SocketAddress kLocalAddress(kLocalIp, kLocalPort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001224
Steve Anton3871f6f2018-01-26 10:25:53 -08001225 constexpr int kRemotePort = 2001;
1226 const std::string kRemoteIp = "192.168.0.2";
1227 const rtc::SocketAddress kRemoteAddress(kRemoteIp, kRemotePort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001228
Steve Anton3871f6f2018-01-26 10:25:53 -08001229 auto pc = CreatePeerConnection();
1230 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001231
Steve Anton3871f6f2018-01-26 10:25:53 -08001232 cricket::Candidate local;
1233 EXPECT_GT(local.id().length(), 0u);
1234 local.set_type(cricket::LOCAL_PORT_TYPE);
1235 local.set_protocol(cricket::UDP_PROTOCOL_NAME);
1236 local.set_address(kLocalAddress);
1237 local.set_priority(kPriority);
1238 local.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001239
Steve Anton3871f6f2018-01-26 10:25:53 -08001240 cricket::Candidate remote;
1241 EXPECT_GT(remote.id().length(), 0u);
1242 remote.set_type(cricket::PRFLX_PORT_TYPE);
1243 remote.set_protocol(cricket::UDP_PROTOCOL_NAME);
1244 remote.set_address(kRemoteAddress);
1245 remote.set_priority(kPriority);
1246 remote.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001247
Steve Anton3871f6f2018-01-26 10:25:53 -08001248 ConnectionInfo connection_info;
1249 connection_info.local_candidate = local;
1250 connection_info.remote_candidate = remote;
1251 TransportChannelStats channel_stats;
1252 channel_stats.connection_infos.push_back(connection_info);
1253
Steve Anton5b387312018-02-02 16:00:20 -08001254 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 10:25:53 -08001255 pc->SetTransportStats(kTransportName, channel_stats);
1256
1257 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1258 StatsReports reports;
1259 stats->GetStats(nullptr, &reports);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001260
1261 // Verify the local candidate report is populated correctly.
1262 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001263 "Cand-" + local.id(),
1264 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1265 StatsReport::kStatsValueNameLocalCandidateId));
1266 EXPECT_EQ(
1267 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001268 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1269 StatsReport::kStatsValueNameCandidateIPAddress));
1270 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001271 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001272 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1273 StatsReport::kStatsValueNameCandidatePortNumber));
1274 EXPECT_EQ(
1275 cricket::UDP_PROTOCOL_NAME,
1276 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1277 StatsReport::kStatsValueNameCandidateTransportType));
1278 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001279 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001280 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1281 StatsReport::kStatsValueNameCandidatePriority));
1282 EXPECT_EQ(
1283 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1284 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1285 StatsReport::kStatsValueNameCandidateType));
1286 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001287 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001288 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1289 StatsReport::kStatsValueNameCandidateNetworkType));
1290
1291 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 10:25:53 -08001292 EXPECT_EQ(
1293 "Cand-" + remote.id(),
1294 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1295 StatsReport::kStatsValueNameRemoteCandidateId));
1296 EXPECT_EQ(kRemoteIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001297 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1298 reports,
1299 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 10:25:53 -08001300 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001301 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1302 reports,
1303 StatsReport::kStatsValueNameCandidatePortNumber));
1304 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1305 ExtractStatsValue(
1306 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1307 StatsReport::kStatsValueNameCandidateTransportType));
Steve Anton3871f6f2018-01-26 10:25:53 -08001308 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001309 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1310 reports,
1311 StatsReport::kStatsValueNameCandidatePriority));
1312 EXPECT_EQ(
1313 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1314 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1315 reports, StatsReport::kStatsValueNameCandidateType));
1316 EXPECT_EQ(kNotFound,
1317 ExtractStatsValue(
1318 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1319 StatsReport::kStatsValueNameCandidateNetworkType));
1320}
1321
wu@webrtc.org4551b792013-10-09 15:37:36 +00001322// This test verifies that all chained certificates are correctly
1323// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001324TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001325 // Build local certificate chain.
1326 std::vector<std::string> local_ders(5);
1327 local_ders[0] = "These";
1328 local_ders[1] = "are";
1329 local_ders[2] = "some";
1330 local_ders[3] = "der";
1331 local_ders[4] = "values";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001332 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001333
1334 // Build remote certificate chain
1335 std::vector<std::string> remote_ders(4);
1336 remote_ders[0] = "A";
1337 remote_ders[1] = "non-";
1338 remote_ders[2] = "intersecting";
1339 remote_ders[3] = "set";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001340 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001341
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001342 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001343 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001344}
1345
1346// This test verifies that all certificates without chains are correctly
1347// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001348TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001349 // Build local certificate.
1350 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001351 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001352
1353 // Build remote certificate.
1354 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001355 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001356
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001357 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1358 remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001359 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001360}
1361
1362// This test verifies that the stats are generated correctly when no
1363// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001364TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001365 auto pc = CreatePeerConnection();
1366 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001367
Steve Anton3871f6f2018-01-26 10:25:53 -08001368 // This will cause the fake PeerConnection to generate a TransportStats entry
1369 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001370 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001371
Steve Anton3871f6f2018-01-26 10:25:53 -08001372 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1373 StatsReports reports;
1374 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001375
1376 // Check that the local certificate is absent.
1377 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001378 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001379 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001380 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001381 ASSERT_EQ(kNotFound, local_certificate_id);
1382
1383 // Check that the remote certificate is absent.
1384 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001385 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001386 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001387 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001388 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001389
1390 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001391 std::string dtls_cipher_suite =
1392 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1393 StatsReport::kStatsValueNameDtlsCipher);
1394 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1395 std::string srtp_crypto_suite =
1396 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1397 StatsReport::kStatsValueNameSrtpCipher);
1398 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001399}
1400
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001401// This test verifies that a remote certificate with an unsupported digest
1402// algorithm is correctly ignored.
1403TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1404 // Build a local certificate.
1405 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001406 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001407
1408 // Build a remote certificate with an unsupported digest algorithm.
1409 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001410 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
1411 remote_cert.set_digest_algorithm("foobar");
1412 rtc::FakeSSLIdentity remote_identity(remote_cert);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001413
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001414 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1415 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001416}
1417
zhihuang6ba3b192016-05-13 11:46:35 -07001418// This test verifies that the audio/video related stats which are -1 initially
1419// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001420TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001421 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001422 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001423 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001424 }
zhihuang6ba3b192016-05-13 11:46:35 -07001425
Steve Anton3871f6f2018-01-26 10:25:53 -08001426 auto pc = CreatePeerConnection();
1427 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001428
1429 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 11:34:10 -08001430 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 11:46:35 -07001431 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1432 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1433 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001434 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001435 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001436 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001437 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001438 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001439
1440 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001441 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001442 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 11:46:35 -07001443 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1444 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001445 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001446 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001447 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001448 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001449 }
zhihuang6ba3b192016-05-13 11:46:35 -07001450
Steve Anton3871f6f2018-01-26 10:25:53 -08001451 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001452 voice_sender_info.add_ssrc(kSsrcOfTrack);
1453 // These values are set to -1 initially in audio_send_stream.
1454 // The voice_sender_info will read the values from audio_send_stream.
1455 voice_sender_info.rtt_ms = -1;
1456 voice_sender_info.packets_lost = -1;
1457 voice_sender_info.jitter_ms = -1;
1458
1459 // Some of the contents in |voice_sender_info| needs to be updated from the
1460 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001461 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1462 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001463
Steve Anton3871f6f2018-01-26 10:25:53 -08001464 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001465 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1466 voice_receiver_info.capture_start_ntp_time_ms = -1;
1467 voice_receiver_info.audio_level = -1;
1468
1469 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001470 VoiceMediaInfo voice_info;
1471 voice_info.senders.push_back(voice_sender_info);
1472 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001473
Steve Anton5b387312018-02-02 16:00:20 -08001474 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1475 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001476
Steve Anton3871f6f2018-01-26 10:25:53 -08001477 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001478
1479 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001480 StatsReports reports;
1481 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001482 const StatsReport* report =
1483 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001484 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001485 // The -1 will not be added to the stats report.
1486 std::string value_in_report;
1487 EXPECT_FALSE(
1488 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1489 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1490 &value_in_report));
1491 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1492 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001493 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1494 &value_in_report));
1495 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1496 &value_in_report));
1497
1498 // Get stats for the remote track.
1499 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001500 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001501 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001502 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001503 EXPECT_FALSE(GetValue(report,
1504 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1505 &value_in_report));
1506 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1507 &value_in_report));
1508}
1509
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001510// This test verifies that a local stats object can get statistics via
1511// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001512TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001513 auto pc = CreatePeerConnection();
1514 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001515
Steve Anton3871f6f2018-01-26 10:25:53 -08001516 AddOutgoingAudioTrack(pc, stats.get());
1517 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001518
Steve Anton3871f6f2018-01-26 10:25:53 -08001519 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001520 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001521 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1522 VoiceMediaInfo voice_info;
1523 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001524
1525 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1526 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001527
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001528 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001529 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001530
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001531 // Verify that there is no remote report for the local audio track because
1532 // we did not set it up.
1533 const StatsReport* remote_report = FindNthReportByType(reports,
1534 StatsReport::kStatsReportTypeRemoteSsrc, 1);
1535 EXPECT_TRUE(remote_report == NULL);
1536}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001537
1538// This test verifies that audio receive streams populate stats reports
1539// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001540TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001541 auto pc = CreatePeerConnection();
1542 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001543
Steve Anton3871f6f2018-01-26 10:25:53 -08001544 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001545
Steve Anton3871f6f2018-01-26 10:25:53 -08001546 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001547 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001548 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001549 VoiceMediaInfo voice_info;
1550 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001551
1552 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1553 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001554
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001555 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001556 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001557}
1558
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001559// This test verifies that a local stats object won't update its statistics
1560// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001561TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001562 auto pc = CreatePeerConnection();
1563 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001564
Steve Anton3871f6f2018-01-26 10:25:53 -08001565 AddOutgoingAudioTrack(pc, stats.get());
1566 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001567
Steve Anton3871f6f2018-01-26 10:25:53 -08001568 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001569 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001570 VoiceMediaInfo voice_info;
1571 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001572
Steve Anton5b387312018-02-02 16:00:20 -08001573 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1574 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001575
Steve Anton3871f6f2018-01-26 10:25:53 -08001576 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001577
Steve Anton3871f6f2018-01-26 10:25:53 -08001578 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1579 StatsReports reports;
1580 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001581
1582 // The report will exist since we don't remove them in RemoveStream().
1583 const StatsReport* report = FindNthReportByType(
1584 reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001585 ASSERT_TRUE(report);
1586 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001587 std::string track_id = ExtractSsrcStatsValue(
1588 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001589 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001590 std::string ssrc_id = ExtractSsrcStatsValue(
1591 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001592 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001593
1594 // Verifies the values in the track report, no value will be changed by the
1595 // AudioTrackInterface::GetSignalValue() and
1596 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1597 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1598}
1599
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001600// This test verifies that when ongoing and incoming audio tracks are using
1601// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001602TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001603 auto pc = CreatePeerConnection();
1604 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001605
1606 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001607 AddOutgoingAudioTrack(pc, stats.get());
1608 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001609
1610 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001611 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001612 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001613 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1614 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001615 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001616 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001617 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001618
Steve Anton3871f6f2018-01-26 10:25:53 -08001619 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001620 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001621 // Some of the contents in |voice_sender_info| needs to be updated from the
1622 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001623 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1624 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001625
Steve Anton3871f6f2018-01-26 10:25:53 -08001626 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001627 InitVoiceReceiverInfo(&voice_receiver_info);
1628
1629 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001630 VoiceMediaInfo voice_info;
1631 voice_info.senders.push_back(voice_sender_info);
1632 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001633
Steve Anton3871f6f2018-01-26 10:25:53 -08001634 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001635 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1636 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001637
Steve Anton3871f6f2018-01-26 10:25:53 -08001638 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001639
1640 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001641 StatsReports reports; // returned values.
1642 stats->GetStats(audio_track_.get(), &reports);
1643
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001644 const StatsReport* track_report = FindNthReportByType(
1645 reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001646 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001647 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001648 std::string track_id = ExtractSsrcStatsValue(
1649 reports, StatsReport::kStatsValueNameTrackId);
1650 EXPECT_EQ(kLocalTrackId, track_id);
1651 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1652
1653 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001654 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001655 stats->GetStats(remote_track.get(), &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001656 track_report = FindNthReportByType(reports,
1657 StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001658 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001659 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001660 track_id = ExtractSsrcStatsValue(reports,
1661 StatsReport::kStatsValueNameTrackId);
1662 EXPECT_EQ(kRemoteTrackId, track_id);
1663 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1664}
1665
xians@webrtc.org01bda202014-07-09 07:38:38 +00001666// This test verifies that when two outgoing audio tracks are using the same
1667// ssrc at different times, they populate stats reports correctly.
1668// TODO(xians): Figure out if it is possible to encapsulate the setup and
1669// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001670TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001671 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001672 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001673 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001674 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001675
Steve Anton3871f6f2018-01-26 10:25:53 -08001676 auto pc = CreatePeerConnection();
1677 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001678
1679 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001680 AddOutgoingAudioTrack(pc, stats.get());
1681 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001682
Steve Anton3871f6f2018-01-26 10:25:53 -08001683 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001684 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001685 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001686 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001687 VoiceMediaInfo voice_info;
1688 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001689
1690 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1691 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001692
xians@webrtc.org01bda202014-07-09 07:38:38 +00001693 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001694 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001695
1696 // Remove the previous audio track from the stream.
1697 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001698 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001699
1700 // Create a new audio track and adds it to the stream and stats.
1701 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001702 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1703 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001704 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001705 stream_->AddTrack(new_audio_track);
1706
Steve Anton3871f6f2018-01-26 10:25:53 -08001707 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1708 stats->ClearUpdateStatsCacheForTest();
1709
1710 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001711 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001712 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1713 false);
1714 VoiceMediaInfo new_voice_info;
1715 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001716 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001717
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001718 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001719 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001720}
1721
sakal43536c32016-10-24 01:46:43 -07001722// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001723TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001724 auto pc = CreatePeerConnection();
1725 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001726
Steve Anton3871f6f2018-01-26 10:25:53 -08001727 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001728
Steve Anton3871f6f2018-01-26 10:25:53 -08001729 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001730 video_sender_info.add_ssrc(1234);
1731 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001732 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001733 VideoMediaInfo video_info;
1734 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001735
1736 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1737 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001738
Steve Anton3871f6f2018-01-26 10:25:53 -08001739 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1740 StatsReports reports;
1741 stats->GetStats(nullptr, &reports);
1742
sakal43536c32016-10-24 01:46:43 -07001743 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1744 ExtractSsrcStatsValue(reports,
1745 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001746 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1747 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001748}
1749
sakale5ba44e2016-10-26 07:09:24 -07001750// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001751TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1752 auto pc = CreatePeerConnection();
1753 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001754
Steve Anton3871f6f2018-01-26 10:25:53 -08001755 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001756
Steve Anton3871f6f2018-01-26 10:25:53 -08001757 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001758 video_receiver_info.add_ssrc(1234);
1759 video_receiver_info.frames_decoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001760 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001761 VideoMediaInfo video_info;
1762 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001763
1764 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1765 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001766
Steve Anton3871f6f2018-01-26 10:25:53 -08001767 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1768 StatsReports reports;
1769 stats->GetStats(nullptr, &reports);
1770
sakale5ba44e2016-10-26 07:09:24 -07001771 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1772 ExtractSsrcStatsValue(reports,
1773 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001774 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1775 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001776}
1777
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001778INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1779
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001780} // namespace webrtc