blob: 46e7bd24cac29fdff1b54cfe5eb12e36d8bfcdf3 [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
kwibergb4d01c42016-04-06 05:15:06 -0700639 void TestCertificateReports(
640 const rtc::FakeSSLCertificate& local_cert,
641 const std::vector<std::string>& local_ders,
kwibergd1fe2812016-04-27 06:47:29 -0700642 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert,
kwibergb4d01c42016-04-06 05:15:06 -0700643 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800644 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000645
Steve Anton3871f6f2018-01-26 10:25:53 -0800646 auto pc = CreatePeerConnection();
647 auto stats = CreateStatsCollector(pc);
648
Steve Anton5b387312018-02-02 16:00:20 -0800649 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000650
651 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800652 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000653 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800654 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700655 channel_stats.ssl_cipher_suite =
656 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800657 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000658
deadbeefcbecd352015-09-23 11:50:27 -0700659 // Fake certificate to report
Henrik Boströmd8281982015-08-27 10:12:24 +0200660 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800661 rtc::RTCCertificate::Create(
662 rtc::MakeUnique<rtc::FakeSSLIdentity>(local_cert)));
663 pc->SetLocalCertificate(kTransportName, local_certificate);
664 pc->SetRemoteCertificate(kTransportName, std::move(remote_cert));
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_)
Steve Anton3871f6f2018-01-26 10:25:53 -0800728 stream_ = MediaStream::Create("streamlabel");
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()) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800743 stream_ = MediaStream::Create("streamlabel");
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_)
Steve Anton3871f6f2018-01-26 10:25:53 -0800761 stream_ = MediaStream::Create("streamlabel");
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)
Steve Anton3871f6f2018-01-26 10:25:53 -0800776 stream_ = MediaStream::Create("streamlabel");
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";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001332 rtc::FakeSSLCertificate local_cert(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";
kwibergd1fe2812016-04-27 06:47:29 -07001340 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001341 new rtc::FakeSSLCertificate(DersToPems(remote_ders)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001342
kwibergb4d01c42016-04-06 05:15:06 -07001343 TestCertificateReports(local_cert, local_ders, std::move(remote_cert),
1344 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001345}
1346
1347// This test verifies that all certificates without chains are correctly
1348// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001349TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001350 // Build local certificate.
1351 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001352 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001353
1354 // Build remote certificate.
1355 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001356 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001357 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001358
1359 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001360 std::move(remote_cert),
1361 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001362}
1363
1364// This test verifies that the stats are generated correctly when no
1365// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001366TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001367 auto pc = CreatePeerConnection();
1368 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001369
Steve Anton3871f6f2018-01-26 10:25:53 -08001370 // This will cause the fake PeerConnection to generate a TransportStats entry
1371 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001372 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001373
Steve Anton3871f6f2018-01-26 10:25:53 -08001374 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1375 StatsReports reports;
1376 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001377
1378 // Check that the local certificate is absent.
1379 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001380 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001381 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001382 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001383 ASSERT_EQ(kNotFound, local_certificate_id);
1384
1385 // Check that the remote certificate is absent.
1386 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001387 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001388 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001389 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001390 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001391
1392 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001393 std::string dtls_cipher_suite =
1394 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1395 StatsReport::kStatsValueNameDtlsCipher);
1396 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1397 std::string srtp_crypto_suite =
1398 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1399 StatsReport::kStatsValueNameSrtpCipher);
1400 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001401}
1402
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001403// This test verifies that a remote certificate with an unsupported digest
1404// algorithm is correctly ignored.
1405TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1406 // Build a local certificate.
1407 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001408 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001409
1410 // Build a remote certificate with an unsupported digest algorithm.
1411 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001412 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001413 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
1414 remote_cert->set_digest_algorithm("foobar");
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001415
1416 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001417 std::move(remote_cert), std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001418}
1419
zhihuang6ba3b192016-05-13 11:46:35 -07001420// This test verifies that the audio/video related stats which are -1 initially
1421// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001422TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001423 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001424 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001425 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001426 }
zhihuang6ba3b192016-05-13 11:46:35 -07001427
Steve Anton3871f6f2018-01-26 10:25:53 -08001428 auto pc = CreatePeerConnection();
1429 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001430
1431 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001432 stream_ = MediaStream::Create("streamlabel");
zhihuang6ba3b192016-05-13 11:46:35 -07001433 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1434 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1435 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001436 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001437 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001438 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001439 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001440 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001441
1442 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001443 rtc::scoped_refptr<MediaStream> remote_stream(
1444 MediaStream::Create("remotestreamlabel"));
zhihuang6ba3b192016-05-13 11:46:35 -07001445 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1446 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001447 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001448 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001449 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001450 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001451 }
zhihuang6ba3b192016-05-13 11:46:35 -07001452
Steve Anton3871f6f2018-01-26 10:25:53 -08001453 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001454 voice_sender_info.add_ssrc(kSsrcOfTrack);
1455 // These values are set to -1 initially in audio_send_stream.
1456 // The voice_sender_info will read the values from audio_send_stream.
1457 voice_sender_info.rtt_ms = -1;
1458 voice_sender_info.packets_lost = -1;
1459 voice_sender_info.jitter_ms = -1;
1460
1461 // Some of the contents in |voice_sender_info| needs to be updated from the
1462 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001463 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1464 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001465
Steve Anton3871f6f2018-01-26 10:25:53 -08001466 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001467 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1468 voice_receiver_info.capture_start_ntp_time_ms = -1;
1469 voice_receiver_info.audio_level = -1;
1470
1471 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001472 VoiceMediaInfo voice_info;
1473 voice_info.senders.push_back(voice_sender_info);
1474 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001475
Steve Anton5b387312018-02-02 16:00:20 -08001476 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1477 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001478
Steve Anton3871f6f2018-01-26 10:25:53 -08001479 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001480
1481 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001482 StatsReports reports;
1483 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001484 const StatsReport* report =
1485 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001486 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001487 // The -1 will not be added to the stats report.
1488 std::string value_in_report;
1489 EXPECT_FALSE(
1490 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1491 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1492 &value_in_report));
1493 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1494 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001495 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1496 &value_in_report));
1497 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1498 &value_in_report));
1499
1500 // Get stats for the remote track.
1501 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001502 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001503 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001504 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001505 EXPECT_FALSE(GetValue(report,
1506 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1507 &value_in_report));
1508 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1509 &value_in_report));
1510}
1511
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001512// This test verifies that a local stats object can get statistics via
1513// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001514TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001515 auto pc = CreatePeerConnection();
1516 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001517
Steve Anton3871f6f2018-01-26 10:25:53 -08001518 AddOutgoingAudioTrack(pc, stats.get());
1519 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001520
Steve Anton3871f6f2018-01-26 10:25:53 -08001521 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001522 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001523 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1524 VoiceMediaInfo voice_info;
1525 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001526
1527 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1528 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001529
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001530 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001531 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001532
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001533 // Verify that there is no remote report for the local audio track because
1534 // we did not set it up.
1535 const StatsReport* remote_report = FindNthReportByType(reports,
1536 StatsReport::kStatsReportTypeRemoteSsrc, 1);
1537 EXPECT_TRUE(remote_report == NULL);
1538}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001539
1540// This test verifies that audio receive streams populate stats reports
1541// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001542TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001543 auto pc = CreatePeerConnection();
1544 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001545
Steve Anton3871f6f2018-01-26 10:25:53 -08001546 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001547
Steve Anton3871f6f2018-01-26 10:25:53 -08001548 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001549 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001550 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001551 VoiceMediaInfo voice_info;
1552 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001553
1554 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1555 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001556
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001557 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001558 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001559}
1560
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001561// This test verifies that a local stats object won't update its statistics
1562// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001563TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001564 auto pc = CreatePeerConnection();
1565 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001566
Steve Anton3871f6f2018-01-26 10:25:53 -08001567 AddOutgoingAudioTrack(pc, stats.get());
1568 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001569
Steve Anton3871f6f2018-01-26 10:25:53 -08001570 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001571 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001572 VoiceMediaInfo voice_info;
1573 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001574
Steve Anton5b387312018-02-02 16:00:20 -08001575 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1576 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001577
Steve Anton3871f6f2018-01-26 10:25:53 -08001578 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001579
Steve Anton3871f6f2018-01-26 10:25:53 -08001580 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1581 StatsReports reports;
1582 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001583
1584 // The report will exist since we don't remove them in RemoveStream().
1585 const StatsReport* report = FindNthReportByType(
1586 reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001587 ASSERT_TRUE(report);
1588 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001589 std::string track_id = ExtractSsrcStatsValue(
1590 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001591 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001592 std::string ssrc_id = ExtractSsrcStatsValue(
1593 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001594 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001595
1596 // Verifies the values in the track report, no value will be changed by the
1597 // AudioTrackInterface::GetSignalValue() and
1598 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1599 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1600}
1601
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001602// This test verifies that when ongoing and incoming audio tracks are using
1603// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001604TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001605 auto pc = CreatePeerConnection();
1606 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001607
1608 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001609 AddOutgoingAudioTrack(pc, stats.get());
1610 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001611
1612 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001613 rtc::scoped_refptr<MediaStream> remote_stream(
1614 MediaStream::Create("remotestreamlabel"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001615 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1616 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001617 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001618 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001619 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001620
Steve Anton3871f6f2018-01-26 10:25:53 -08001621 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001622 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001623 // Some of the contents in |voice_sender_info| needs to be updated from the
1624 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001625 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1626 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001627
Steve Anton3871f6f2018-01-26 10:25:53 -08001628 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001629 InitVoiceReceiverInfo(&voice_receiver_info);
1630
1631 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001632 VoiceMediaInfo voice_info;
1633 voice_info.senders.push_back(voice_sender_info);
1634 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001635
Steve Anton3871f6f2018-01-26 10:25:53 -08001636 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001637 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1638 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001639
Steve Anton3871f6f2018-01-26 10:25:53 -08001640 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001641
1642 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001643 StatsReports reports; // returned values.
1644 stats->GetStats(audio_track_.get(), &reports);
1645
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001646 const StatsReport* track_report = FindNthReportByType(
1647 reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001648 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001649 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001650 std::string track_id = ExtractSsrcStatsValue(
1651 reports, StatsReport::kStatsValueNameTrackId);
1652 EXPECT_EQ(kLocalTrackId, track_id);
1653 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1654
1655 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001656 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001657 stats->GetStats(remote_track.get(), &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001658 track_report = FindNthReportByType(reports,
1659 StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001660 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001661 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001662 track_id = ExtractSsrcStatsValue(reports,
1663 StatsReport::kStatsValueNameTrackId);
1664 EXPECT_EQ(kRemoteTrackId, track_id);
1665 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1666}
1667
xians@webrtc.org01bda202014-07-09 07:38:38 +00001668// This test verifies that when two outgoing audio tracks are using the same
1669// ssrc at different times, they populate stats reports correctly.
1670// TODO(xians): Figure out if it is possible to encapsulate the setup and
1671// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001672TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001673 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001674 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001675 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001676 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001677
Steve Anton3871f6f2018-01-26 10:25:53 -08001678 auto pc = CreatePeerConnection();
1679 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001680
1681 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001682 AddOutgoingAudioTrack(pc, stats.get());
1683 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001684
Steve Anton3871f6f2018-01-26 10:25:53 -08001685 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001686 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001687 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001688 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001689 VoiceMediaInfo voice_info;
1690 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001691
1692 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1693 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001694
xians@webrtc.org01bda202014-07-09 07:38:38 +00001695 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001696 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001697
1698 // Remove the previous audio track from the stream.
1699 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001700 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001701
1702 // Create a new audio track and adds it to the stream and stats.
1703 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001704 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1705 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001706 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001707 stream_->AddTrack(new_audio_track);
1708
Steve Anton3871f6f2018-01-26 10:25:53 -08001709 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1710 stats->ClearUpdateStatsCacheForTest();
1711
1712 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001713 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001714 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1715 false);
1716 VoiceMediaInfo new_voice_info;
1717 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001718 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001719
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001720 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001721 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001722}
1723
sakal43536c32016-10-24 01:46:43 -07001724// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001725TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001726 auto pc = CreatePeerConnection();
1727 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001728
Steve Anton3871f6f2018-01-26 10:25:53 -08001729 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001730
Steve Anton3871f6f2018-01-26 10:25:53 -08001731 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001732 video_sender_info.add_ssrc(1234);
1733 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001734 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001735 VideoMediaInfo video_info;
1736 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001737
1738 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1739 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001740
Steve Anton3871f6f2018-01-26 10:25:53 -08001741 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1742 StatsReports reports;
1743 stats->GetStats(nullptr, &reports);
1744
sakal43536c32016-10-24 01:46:43 -07001745 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1746 ExtractSsrcStatsValue(reports,
1747 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001748 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1749 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001750}
1751
sakale5ba44e2016-10-26 07:09:24 -07001752// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001753TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1754 auto pc = CreatePeerConnection();
1755 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001756
Steve Anton3871f6f2018-01-26 10:25:53 -08001757 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001758
Steve Anton3871f6f2018-01-26 10:25:53 -08001759 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001760 video_receiver_info.add_ssrc(1234);
1761 video_receiver_info.frames_decoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001762 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001763 VideoMediaInfo video_info;
1764 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001765
1766 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1767 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001768
Steve Anton3871f6f2018-01-26 10:25:53 -08001769 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1770 StatsReports reports;
1771 stats->GetStats(nullptr, &reports);
1772
sakale5ba44e2016-10-26 07:09:24 -07001773 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1774 ExtractSsrcStatsValue(reports,
1775 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001776 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1777 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001778}
1779
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001780INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1781
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001782} // namespace webrtc