blob: 4fdb8cd240076836eca8691e104cf0dfc100a018 [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>
deadbeefcbecd352015-09-23 11:50:27 -070012#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070013#include <memory>
deadbeefcbecd352015-09-23 11:50:27 -070014
Yves Gerey3e707812018-11-28 16:47:49 +010015#include "absl/memory/memory.h"
16#include "absl/types/optional.h"
17#include "api/audio_codecs/audio_encoder.h"
18#include "api/candidate.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/data_channel_interface.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "call/call.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "media/base/media_channel.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "modules/audio_processing/include/audio_processing_statistics.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "pc/data_channel.h"
24#include "pc/media_stream.h"
25#include "pc/media_stream_track.h"
26#include "pc/stats_collector.h"
27#include "pc/test/fake_peer_connection_for_stats.h"
28#include "pc/test/fake_video_track_source.h"
29#include "pc/transport_stats.h"
30#include "pc/video_track.h"
31#include "rtc_base/fake_ssl_identity.h"
32#include "rtc_base/message_digest.h"
33#include "rtc_base/net_helper.h"
34#include "rtc_base/ref_counted_object.h"
35#include "rtc_base/rtc_certificate.h"
Yves Gerey3e707812018-11-28 16:47:49 +010036#include "rtc_base/scoped_ref_ptr.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "rtc_base/socket_address.h"
38#include "rtc_base/ssl_identity.h"
39#include "rtc_base/ssl_stream_adapter.h"
40#include "rtc_base/string_encode.h"
Artem Titova76af0c2018-07-23 17:38:12 +020041#include "rtc_base/third_party/base64/base64.h"
Yves Gerey3e707812018-11-28 16:47:49 +010042#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020043#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044
Steve Anton3871f6f2018-01-26 10:25:53 -080045using cricket::ConnectionInfo;
46using cricket::SsrcReceiverInfo;
47using cricket::TransportChannelStats;
48using cricket::VideoMediaInfo;
49using cricket::VideoReceiverInfo;
50using cricket::VideoSenderInfo;
51using cricket::VoiceMediaInfo;
52using cricket::VoiceReceiverInfo;
53using cricket::VoiceSenderInfo;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000055namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056
tkchin7d06a8c2016-04-04 14:10:43 -070057namespace internal {
58// This value comes from openssl/tls1.h
59static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
60} // namespace internal
61
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062// Error return values
63const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064
wu@webrtc.org97077a32013-10-25 21:18:33 +000065// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000066const char kLocalTrackId[] = "local_track_id";
67const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020068const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000069
Steve Anton3871f6f2018-01-26 10:25:53 -080070class FakeAudioProcessor : public AudioProcessorInterface {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000071 public:
72 FakeAudioProcessor() {}
73 ~FakeAudioProcessor() {}
74
75 private:
Ivo Creusenae026092017-11-20 13:07:16 +010076 AudioProcessorInterface::AudioProcessorStatistics GetStats(
Ivo Creusen56d46092017-11-24 17:29:59 +010077 bool has_recv_streams) override {
Ivo Creusenae026092017-11-20 13:07:16 +010078 AudioProcessorStatistics stats;
79 stats.typing_noise_detected = true;
Ivo Creusen56d46092017-11-24 17:29:59 +010080 if (has_recv_streams) {
81 stats.apm_statistics.echo_return_loss = 2.0;
82 stats.apm_statistics.echo_return_loss_enhancement = 3.0;
83 stats.apm_statistics.delay_median_ms = 4;
84 stats.apm_statistics.delay_standard_deviation_ms = 5;
85 }
Ivo Creusenae026092017-11-20 13:07:16 +010086 return stats;
87 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000088};
89
Steve Anton3871f6f2018-01-26 10:25:53 -080090class FakeAudioTrack : public MediaStreamTrack<AudioTrackInterface> {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000091 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +000092 explicit FakeAudioTrack(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -080093 : MediaStreamTrack<AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000094 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000095 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -080096 AudioSourceInterface* GetSource() const override { return NULL; }
97 void AddSink(AudioTrackSinkInterface* sink) override {}
98 void RemoveSink(AudioTrackSinkInterface* sink) override {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000099 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000100 *level = 1;
101 return true;
102 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800103 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000104 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000105 }
106
107 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000108 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000109};
110
zhihuang6ba3b192016-05-13 11:46:35 -0700111// This fake audio processor is used to verify that the undesired initial values
112// (-1) will be filtered out.
Steve Anton3871f6f2018-01-26 10:25:53 -0800113class FakeAudioProcessorWithInitValue : public AudioProcessorInterface {
zhihuang6ba3b192016-05-13 11:46:35 -0700114 public:
115 FakeAudioProcessorWithInitValue() {}
116 ~FakeAudioProcessorWithInitValue() {}
117
118 private:
Ivo Creusenae026092017-11-20 13:07:16 +0100119 AudioProcessorInterface::AudioProcessorStatistics GetStats(
120 bool /*has_recv_streams*/) override {
121 AudioProcessorStatistics stats;
122 stats.typing_noise_detected = false;
123 return stats;
124 }
zhihuang6ba3b192016-05-13 11:46:35 -0700125};
126
127class FakeAudioTrackWithInitValue
Steve Anton3871f6f2018-01-26 10:25:53 -0800128 : public MediaStreamTrack<AudioTrackInterface> {
zhihuang6ba3b192016-05-13 11:46:35 -0700129 public:
130 explicit FakeAudioTrackWithInitValue(const std::string& id)
Steve Anton3871f6f2018-01-26 10:25:53 -0800131 : MediaStreamTrack<AudioTrackInterface>(id),
zhihuang6ba3b192016-05-13 11:46:35 -0700132 processor_(
133 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
134 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 10:25:53 -0800135 AudioSourceInterface* GetSource() const override { return NULL; }
136 void AddSink(AudioTrackSinkInterface* sink) override {}
137 void RemoveSink(AudioTrackSinkInterface* sink) override {}
zhihuang6ba3b192016-05-13 11:46:35 -0700138 bool GetSignalLevel(int* level) override {
139 *level = 1;
140 return true;
141 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800142 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
zhihuang6ba3b192016-05-13 11:46:35 -0700143 return processor_;
144 }
145
146 private:
147 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
148};
149
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000150bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000151 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000152 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000153 const StatsReport::Value* v = report->FindValue(name);
154 if (!v)
155 return false;
156 *value = v->ToString();
157 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000158}
159
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000160std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000161 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000162 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000163 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000164 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000165 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000166 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 }
168
169 return kNotFound;
170}
171
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000172StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
173 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000174 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000175 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000176 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000177 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000178
179 // This has assumptions about how the ID is constructed. As is, this is
180 // OK since this is for testing purposes only, but if we ever need this
181 // in production, we should add a generic method that does this.
182 size_t index = value.find('_');
183 EXPECT_NE(index, std::string::npos);
184 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000185 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000186
187 id = StatsReport::NewTypedId(type, value.substr(index + 1));
188 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000189 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000190}
191
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000192StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
193 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000194}
195
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196// Finds the |n|-th report of type |type| in |reports|.
197// |n| starts from 1 for finding the first report.
Yves Gerey665174f2018-06-19 15:03:05 +0200198const StatsReport* FindNthReportByType(const StatsReports& reports,
199 const StatsReport::StatsType& type,
200 int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000202 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 n--;
204 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000205 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 }
207 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000208 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209}
210
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000211const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000212 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000213 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000214 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000215 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000217 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218}
219
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100220std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000221 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000222 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223}
224
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100225std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000226 StatsReport::StatsValueName name) {
Yves Gerey665174f2018-06-19 15:03:05 +0200227 return ExtractStatsValue(StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228}
229
wu@webrtc.org4551b792013-10-09 15:37:36 +0000230std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000231 return rtc::SSLIdentity::DerToPem(
Yves Gerey665174f2018-06-19 15:03:05 +0200232 rtc::kPemTypeCertificate,
233 reinterpret_cast<const unsigned char*>(der.c_str()), der.length());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000234}
235
Yves Gerey665174f2018-06-19 15:03:05 +0200236std::vector<std::string> DersToPems(const std::vector<std::string>& ders) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000237 std::vector<std::string> pems(ders.size());
238 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
239 return pems;
240}
241
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000242void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000243 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000244 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000245 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000246 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000247 size_t i = 0;
248 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000249 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000250 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000251
wu@webrtc.org4551b792013-10-09 15:37:36 +0000252 std::string der_base64;
Yves Gerey665174f2018-06-19 15:03:05 +0200253 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000254 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000255 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000256
257 std::string fingerprint_algorithm;
Yves Gerey665174f2018-06-19 15:03:05 +0200258 EXPECT_TRUE(GetValue(report,
259 StatsReport::kStatsValueNameFingerprintAlgorithm,
260 &fingerprint_algorithm));
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000261 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000262 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000263 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
264
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000265 std::string fingerprint;
266 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
267 &fingerprint));
268 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000269
wu@webrtc.org4551b792013-10-09 15:37:36 +0000270 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000271 std::string issuer_id;
Yves Gerey665174f2018-06-19 15:03:05 +0200272 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId, &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000273 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000274 }
275
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000276 cert_id = IdFromCertIdString(issuer_id);
277 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000278 }
279 EXPECT_EQ(ders.size(), i);
280}
281
Yves Gerey665174f2018-06-19 15:03:05 +0200282void VerifyVoiceReceiverInfoReport(const StatsReport* report,
283 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000284 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200285 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioOutputLevel,
286 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200287 EXPECT_EQ(rtc::ToString(info.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200288 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived,
289 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200290 EXPECT_EQ(rtc::ToString(info.bytes_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200291 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
292 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200293 EXPECT_EQ(rtc::ToString(info.jitter_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200294 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterBufferMs,
295 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200296 EXPECT_EQ(rtc::ToString(info.jitter_buffer_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200297 EXPECT_TRUE(GetValue(report,
298 StatsReport::kStatsValueNamePreferredJitterBufferMs,
299 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200300 EXPECT_EQ(rtc::ToString(info.jitter_buffer_preferred_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200301 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCurrentDelayMs,
302 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200303 EXPECT_EQ(rtc::ToString(info.delay_estimate_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200304 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameExpandRate,
305 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200306 EXPECT_EQ(rtc::ToString(info.expand_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200307 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSpeechExpandRate,
308 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200309 EXPECT_EQ(rtc::ToString(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200310 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
311 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200312 EXPECT_EQ(rtc::ToString(info.accelerate_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200313 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
314 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200315 EXPECT_EQ(rtc::ToString(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000316 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
317 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200318 EXPECT_EQ(rtc::ToString(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200319 EXPECT_TRUE(GetValue(report,
320 StatsReport::kStatsValueNameSecondaryDiscardedRate,
321 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200322 EXPECT_EQ(rtc::ToString(info.secondary_discarded_rate), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200323 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived,
324 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200325 EXPECT_EQ(rtc::ToString(info.packets_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200326 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG,
327 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200328 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_silence_generator),
Yves Gerey665174f2018-06-19 15:03:05 +0200329 value_in_report);
330 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTN,
331 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200332 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_neteq), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200333 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingNormal,
334 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200335 EXPECT_EQ(rtc::ToString(info.decoding_normal), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200336 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
337 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200338 EXPECT_EQ(rtc::ToString(info.decoding_plc), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200339 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
340 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200341 EXPECT_EQ(rtc::ToString(info.decoding_cng), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200342 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLCCNG,
343 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200344 EXPECT_EQ(rtc::ToString(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700345 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
346 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200347 EXPECT_EQ(rtc::ToString(info.decoding_muted_output), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700348 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
349 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000350}
351
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000352void VerifyVoiceSenderInfoReport(const StatsReport* report,
353 const cricket::VoiceSenderInfo& sinfo) {
354 std::string value_in_report;
Yves Gerey665174f2018-06-19 15:03:05 +0200355 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
356 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000357 EXPECT_EQ(sinfo.codec_name, value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200358 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesSent,
359 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200360 EXPECT_EQ(rtc::ToString(sinfo.bytes_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200361 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsSent,
362 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200363 EXPECT_EQ(rtc::ToString(sinfo.packets_sent), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200364 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
365 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200366 EXPECT_EQ(rtc::ToString(sinfo.packets_lost), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200367 EXPECT_TRUE(
368 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200369 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200370 EXPECT_TRUE(
371 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200372 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200373 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
374 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200375 EXPECT_EQ(rtc::ToString(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100376 if (sinfo.apm_statistics.delay_median_ms) {
377 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
378 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200379 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_median_ms),
Ivo Creusen56d46092017-11-24 17:29:59 +0100380 value_in_report);
381 } else {
382 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
383 &value_in_report));
384 }
385 if (sinfo.apm_statistics.delay_standard_deviation_ms) {
386 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
387 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200388 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_standard_deviation_ms),
389 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100390 } else {
391 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
392 &value_in_report));
393 }
394 if (sinfo.apm_statistics.echo_return_loss) {
395 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
396 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200397 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss),
Ivo Creusen56d46092017-11-24 17:29:59 +0100398 value_in_report);
399 } else {
400 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoReturnLoss,
401 &value_in_report));
402 }
403 if (sinfo.apm_statistics.echo_return_loss_enhancement) {
404 EXPECT_TRUE(GetValue(report,
405 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
406 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200407 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss_enhancement),
408 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100409 } else {
410 EXPECT_FALSE(GetValue(report,
411 StatsReport::kStatsValueNameEchoReturnLossEnhancement,
412 &value_in_report));
413 }
414 if (sinfo.apm_statistics.residual_echo_likelihood) {
415 EXPECT_TRUE(GetValue(report,
416 StatsReport::kStatsValueNameResidualEchoLikelihood,
417 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200418 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.residual_echo_likelihood),
419 value_in_report);
Ivo Creusen56d46092017-11-24 17:29:59 +0100420 } else {
421 EXPECT_FALSE(GetValue(report,
422 StatsReport::kStatsValueNameResidualEchoLikelihood,
423 &value_in_report));
424 }
425 if (sinfo.apm_statistics.residual_echo_likelihood_recent_max) {
426 EXPECT_TRUE(GetValue(
427 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
428 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200429 EXPECT_EQ(rtc::ToString(
Ivo Creusen56d46092017-11-24 17:29:59 +0100430 *sinfo.apm_statistics.residual_echo_likelihood_recent_max),
431 value_in_report);
432 } else {
433 EXPECT_FALSE(GetValue(
434 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
435 &value_in_report));
436 }
ivoc8c63a822016-10-21 04:10:03 -0700437 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
438 &value_in_report));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200439 EXPECT_EQ(rtc::ToString(sinfo.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 15:03:05 +0200440 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameTypingNoiseState,
441 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000442 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
443 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700444 EXPECT_TRUE(GetValue(report,
445 StatsReport::kStatsValueNameAnaBitrateActionCounter,
446 &value_in_report));
447 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200448 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.bitrate_action_counter),
449 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700450 EXPECT_TRUE(GetValue(report,
451 StatsReport::kStatsValueNameAnaChannelActionCounter,
452 &value_in_report));
453 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200454 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.channel_action_counter),
455 value_in_report);
ivoce1198e02017-09-08 08:13:19 -0700456 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
457 &value_in_report));
458 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200459 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.dtx_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700460 value_in_report);
461 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter,
462 &value_in_report));
463 ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200464 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.fec_action_counter),
ivoce1198e02017-09-08 08:13:19 -0700465 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700466 EXPECT_TRUE(GetValue(
467 report, StatsReport::kStatsValueNameAnaFrameLengthIncreaseCounter,
468 &value_in_report));
469 ASSERT_TRUE(sinfo.ana_statistics.frame_length_increase_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200470 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 08:13:19 -0700471 value_in_report);
ivoc0d0b9122017-09-08 13:24:21 -0700472 EXPECT_TRUE(GetValue(
473 report, StatsReport::kStatsValueNameAnaFrameLengthDecreaseCounter,
474 &value_in_report));
475 ASSERT_TRUE(sinfo.ana_statistics.frame_length_decrease_counter);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200476 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_decrease_counter),
ivoc0d0b9122017-09-08 13:24:21 -0700477 value_in_report);
478 EXPECT_TRUE(GetValue(report,
479 StatsReport::kStatsValueNameAnaUplinkPacketLossFraction,
480 &value_in_report));
481 ASSERT_TRUE(sinfo.ana_statistics.uplink_packet_loss_fraction);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200482 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.uplink_packet_loss_fraction),
483 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000484}
485
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000486// Helper methods to avoid duplication of code.
487void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
488 voice_sender_info->add_ssrc(kSsrcOfTrack);
489 voice_sender_info->codec_name = "fake_codec";
490 voice_sender_info->bytes_sent = 100;
491 voice_sender_info->packets_sent = 101;
492 voice_sender_info->rtt_ms = 102;
493 voice_sender_info->fraction_lost = 103;
494 voice_sender_info->jitter_ms = 104;
495 voice_sender_info->packets_lost = 105;
496 voice_sender_info->ext_seqnum = 106;
497 voice_sender_info->audio_level = 107;
Sam Zackrisson5f2ffee2018-11-01 13:51:24 +0100498 voice_sender_info->apm_statistics.echo_return_loss = 108;
499 voice_sender_info->apm_statistics.echo_return_loss_enhancement = 109;
500 voice_sender_info->apm_statistics.delay_median_ms = 110;
501 voice_sender_info->apm_statistics.delay_standard_deviation_ms = 111;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000502 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d46092017-11-24 17:29:59 +0100503 voice_sender_info->ana_statistics.bitrate_action_counter = 112;
504 voice_sender_info->ana_statistics.channel_action_counter = 113;
505 voice_sender_info->ana_statistics.dtx_action_counter = 114;
506 voice_sender_info->ana_statistics.fec_action_counter = 115;
507 voice_sender_info->ana_statistics.frame_length_increase_counter = 116;
508 voice_sender_info->ana_statistics.frame_length_decrease_counter = 117;
509 voice_sender_info->ana_statistics.uplink_packet_loss_fraction = 118.0;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000510}
511
512void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700513 AudioTrackInterface* audio_track,
Ivo Creusen56d46092017-11-24 17:29:59 +0100514 cricket::VoiceSenderInfo* voice_sender_info,
515 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000516 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 10:25:53 -0800517 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
518 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000519 voice_sender_info->typing_noise_detected =
520 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d46092017-11-24 17:29:59 +0100521 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000522}
523
524void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
525 voice_receiver_info->add_ssrc(kSsrcOfTrack);
526 voice_receiver_info->bytes_rcvd = 110;
527 voice_receiver_info->packets_rcvd = 111;
528 voice_receiver_info->packets_lost = 112;
529 voice_receiver_info->fraction_lost = 113;
530 voice_receiver_info->packets_lost = 114;
531 voice_receiver_info->ext_seqnum = 115;
532 voice_receiver_info->jitter_ms = 116;
533 voice_receiver_info->jitter_buffer_ms = 117;
534 voice_receiver_info->jitter_buffer_preferred_ms = 118;
535 voice_receiver_info->delay_estimate_ms = 119;
536 voice_receiver_info->audio_level = 120;
537 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000538 voice_receiver_info->speech_expand_rate = 122;
539 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200540 voice_receiver_info->accelerate_rate = 124;
541 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200542 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000543}
544
Steve Anton3871f6f2018-01-26 10:25:53 -0800545class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000546 public:
Steve Anton3871f6f2018-01-26 10:25:53 -0800547 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 11:33:11 -0700548 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000549
Yves Gerey665174f2018-06-19 15:03:05 +0200550 double GetTimeNow() override { return time_now_; }
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000551
552 private:
553 double time_now_;
554};
555
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556class StatsCollectorTest : public testing::Test {
557 protected:
Steve Anton3871f6f2018-01-26 10:25:53 -0800558 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
559 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 }
561
Steve Anton3871f6f2018-01-26 10:25:53 -0800562 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
563 PeerConnectionInternal* pc) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200564 return absl::make_unique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000565 }
566
Steve Anton3871f6f2018-01-26 10:25:53 -0800567 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
568 StatsCollectorForTest* stats,
569 const VoiceMediaInfo& voice_info,
570 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38 +0000571 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000572 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 10:25:53 -0800573 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000574
575 // Verify the existence of the track report.
Yves Gerey665174f2018-06-19 15:03:05 +0200576 const StatsReport* report =
577 FindNthReportByType(*reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800578 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 15:06:43 -0700579 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +0200580 std::string track_id =
581 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000582 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200583 std::string ssrc_id =
584 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200585 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000586
Yves Gerey665174f2018-06-19 15:03:05 +0200587 std::string media_type =
588 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -0800589 EXPECT_EQ("audio", media_type);
590
xians@webrtc.org01bda202014-07-09 07:38:38 +0000591 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 10:25:53 -0800592 if (!voice_info.senders.empty()) {
593 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000594 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800595 if (!voice_info.receivers.empty()) {
596 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000597 }
598
599 // Verify we get the same result by passing a track to GetStats().
600 StatsReports track_reports; // returned values.
601 stats->GetStats(audio_track, &track_reports);
602 const StatsReport* track_report = FindNthReportByType(
603 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800604 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700605 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000606 track_id = ExtractSsrcStatsValue(track_reports,
607 StatsReport::kStatsValueNameTrackId);
608 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 15:03:05 +0200609 ssrc_id =
610 ExtractSsrcStatsValue(track_reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200611 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 10:25:53 -0800612 if (!voice_info.senders.empty()) {
613 VerifyVoiceSenderInfoReport(track_report, voice_info.senders[0]);
614 }
615 if (!voice_info.receivers.empty()) {
616 VerifyVoiceReceiverInfoReport(track_report, voice_info.receivers[0]);
617 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000618 }
619
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800620 void TestCertificateReports(const rtc::FakeSSLIdentity& local_identity,
621 const std::vector<std::string>& local_ders,
622 const rtc::FakeSSLIdentity& remote_identity,
623 const std::vector<std::string>& remote_ders) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800624 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000625
Steve Anton3871f6f2018-01-26 10:25:53 -0800626 auto pc = CreatePeerConnection();
627 auto stats = CreateStatsCollector(pc);
628
Steve Anton5b387312018-02-02 16:00:20 -0800629 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000630
631 // Fake stats to process.
Steve Anton3871f6f2018-01-26 10:25:53 -0800632 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000633 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800634 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700635 channel_stats.ssl_cipher_suite =
636 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 10:25:53 -0800637 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000638
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800639 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 10:12:24 +0200640 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 10:25:53 -0800641 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800642 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 10:25:53 -0800643 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800644 pc->SetRemoteCertChain(kTransportName,
Steve Antonf25303e2018-10-16 15:23:31 -0700645 remote_identity.cert_chain().Clone());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000646
Steve Anton3871f6f2018-01-26 10:25:53 -0800647 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000648
Steve Anton3871f6f2018-01-26 10:25:53 -0800649 StatsReports reports;
650 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000651
Yves Gerey665174f2018-06-19 15:03:05 +0200652 const StatsReport* channel_report =
653 FindNthReportByType(reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -0800654 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000655
656 // Check local certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200657 std::string local_certificate_id =
658 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
659 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000660 if (local_ders.size() > 0) {
661 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000662 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
663 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000664 } else {
665 EXPECT_EQ(kNotFound, local_certificate_id);
666 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000667
668 // Check remote certificate chain.
Yves Gerey665174f2018-06-19 15:03:05 +0200669 std::string remote_certificate_id =
670 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
671 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000672 if (remote_ders.size() > 0) {
673 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000674 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
675 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000676 } else {
677 EXPECT_EQ(kNotFound, remote_certificate_id);
678 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000679
680 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800681 std::string dtls_cipher_suite =
682 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
683 StatsReport::kStatsValueNameDtlsCipher);
684 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700685 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800686 dtls_cipher_suite);
687 std::string srtp_crypto_suite =
688 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
689 StatsReport::kStatsValueNameSrtpCipher);
690 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
691 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000692 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100693};
694
695class StatsCollectorTrackTest : public StatsCollectorTest,
696 public ::testing::WithParamInterface<bool> {
697 public:
698 // Adds a outgoing video track with a given SSRC into the stats.
699 // If GetParam() returns true, the track is also inserted into the local
700 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800701 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
702 StatsCollectorForTest* stats) {
703 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
704 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100705 if (GetParam()) {
706 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800707 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100708 stream_->AddTrack(track_);
709 stats->AddStream(stream_);
710 } else {
711 stats->AddTrack(track_);
712 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800713 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100714 }
715
716 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800717 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
718 StatsCollectorForTest* stats) {
719 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
720 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100721 if (GetParam()) {
Seth Hampson845e8782018-03-02 11:34:10 -0800722 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100723 stream_->AddTrack(track_);
724 stats->AddStream(stream_);
725 } else {
726 stats->AddTrack(track_);
727 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800728 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100729 }
730
731 // Adds a outgoing audio track with a given SSRC into the stats,
732 // and register it into the stats object.
733 // If GetParam() returns true, the track is also inserted into the local
734 // stream, which is created if necessary.
Steve Anton3871f6f2018-01-26 10:25:53 -0800735 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
736 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100737 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
738 if (GetParam()) {
739 if (!stream_)
Seth Hampson845e8782018-03-02 11:34:10 -0800740 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100741 stream_->AddTrack(audio_track_);
742 stats->AddStream(stream_);
743 } else {
744 stats->AddTrack(audio_track_);
745 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800746 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100747 }
748
749 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -0800750 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
751 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100752 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
753 if (GetParam()) {
754 if (stream_ == NULL)
Seth Hampson845e8782018-03-02 11:34:10 -0800755 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100756 stream_->AddTrack(audio_track_);
757 stats->AddStream(stream_);
758 } else {
759 stats->AddTrack(audio_track_);
760 }
Steve Anton3871f6f2018-01-26 10:25:53 -0800761 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100762 }
763
Steve Anton3871f6f2018-01-26 10:25:53 -0800764 rtc::scoped_refptr<MediaStream> stream_;
765 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000766 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767};
768
zhihuang6ba3b192016-05-13 11:46:35 -0700769TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800770 auto pc = CreatePeerConnection();
771 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -0700772
Steve Anton3871f6f2018-01-26 10:25:53 -0800773 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 11:46:35 -0700774
Steve Anton3871f6f2018-01-26 10:25:53 -0800775 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -0700776 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800777 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 11:46:35 -0700778
779 const StatsReport* report =
780 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
781
782 std::string value_in_report;
783 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
784 &value_in_report));
785}
786
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000787// Verify that ExtractDataInfo populates reports.
788TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800789 const std::string kDataChannelLabel = "hacks";
790 constexpr int kDataChannelId = 31337;
791 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000792 DataChannelInterface::DataState::kConnecting);
793
Steve Anton3871f6f2018-01-26 10:25:53 -0800794 auto pc = CreatePeerConnection();
795 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000796
Steve Anton3871f6f2018-01-26 10:25:53 -0800797 InternalDataChannelInit init;
798 init.id = kDataChannelId;
799 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000800
Steve Anton3871f6f2018-01-26 10:25:53 -0800801 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000802 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800803 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000804
805 const StatsReport* report =
806 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
807
Steve Anton3871f6f2018-01-26 10:25:53 -0800808 StatsReport::Id report_id = StatsReport::NewTypedIntId(
809 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000810
Steve Anton3871f6f2018-01-26 10:25:53 -0800811 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000812
Steve Anton3871f6f2018-01-26 10:25:53 -0800813 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
814 EXPECT_EQ(kDataChannelLabel,
815 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
816 StatsReport::kStatsValueNameLabel));
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200817 EXPECT_EQ(rtc::ToString(kDataChannelId),
Peter Boström0c4e06b2015-10-07 12:23:21 +0200818 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000819 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 10:25:53 -0800820 EXPECT_EQ(kConnectingString,
821 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
822 StatsReport::kStatsValueNameState));
Yves Gerey665174f2018-06-19 15:03:05 +0200823 EXPECT_EQ("",
824 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
825 StatsReport::kStatsValueNameProtocol));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000826}
827
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100829TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 10:25:53 -0800831 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
Steve Anton3871f6f2018-01-26 10:25:53 -0800833 auto pc = CreatePeerConnection();
834 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835
Steve Anton3871f6f2018-01-26 10:25:53 -0800836 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000837 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800839 VideoMediaInfo video_info;
840 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800841
842 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
843 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844
Steve Anton3871f6f2018-01-26 10:25:53 -0800845 AddOutgoingVideoTrack(pc, stats.get());
846
847 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
848 StatsReports reports;
849 stats->GetStats(nullptr, &reports);
850
851 EXPECT_EQ(
852 rtc::ToString(kBytesSent),
853 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854}
855
Alex Narest42308f62017-06-19 17:58:12 +0200856// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100857TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 17:58:12 +0200858 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
859 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800860 constexpr int64_t kBytesSent = 12345678901234LL;
861 constexpr int kSendBandwidth = 1234567;
862 constexpr int kRecvBandwidth = 12345678;
863 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 17:58:12 +0200864
Steve Anton3871f6f2018-01-26 10:25:53 -0800865 auto pc = CreatePeerConnection();
866 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 17:58:12 +0200867
Steve Anton3871f6f2018-01-26 10:25:53 -0800868 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 17:58:12 +0200869 voice_sender_info.add_ssrc(1234);
870 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800871 VoiceMediaInfo voice_info;
872 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800873
874 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
875 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 17:58:12 +0200876
Steve Anton3871f6f2018-01-26 10:25:53 -0800877 AddOutgoingAudioTrack(pc, stats.get());
878
879 Call::Stats call_stats;
Alex Narest42308f62017-06-19 17:58:12 +0200880 call_stats.send_bandwidth_bps = kSendBandwidth;
881 call_stats.recv_bandwidth_bps = kRecvBandwidth;
882 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800883 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 17:58:12 +0200884
Steve Anton3871f6f2018-01-26 10:25:53 -0800885 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
886 StatsReports reports;
887 stats->GetStats(nullptr, &reports);
888
889 EXPECT_EQ(
890 rtc::ToString(kBytesSent),
891 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
892 EXPECT_EQ(rtc::ToString(kSendBandwidth),
893 ExtractBweStatsValue(
894 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
895 EXPECT_EQ(
896 rtc::ToString(kRecvBandwidth),
897 ExtractBweStatsValue(
898 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
899 EXPECT_EQ(
900 rtc::ToString(kPacerDelay),
901 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
Alex Narest42308f62017-06-19 17:58:12 +0200902}
903
904// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100905TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
907 // BWE.
Steve Anton3871f6f2018-01-26 10:25:53 -0800908 constexpr int64_t kBytesSent = 12345678901234LL;
909 constexpr int kSendBandwidth = 1234567;
910 constexpr int kRecvBandwidth = 12345678;
911 constexpr int kPacerDelay = 123;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912
Steve Anton3871f6f2018-01-26 10:25:53 -0800913 auto pc = CreatePeerConnection();
914 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915
Steve Anton3871f6f2018-01-26 10:25:53 -0800916 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000917 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -0800919 VideoMediaInfo video_info;
920 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -0800921
922 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
923 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924
Steve Anton3871f6f2018-01-26 10:25:53 -0800925 AddOutgoingVideoTrack(pc, stats.get());
926
927 Call::Stats call_stats;
stefanf79ade12017-06-02 06:44:03 -0700928 call_stats.send_bandwidth_bps = kSendBandwidth;
929 call_stats.recv_bandwidth_bps = kRecvBandwidth;
930 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 10:25:53 -0800931 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000932
Steve Anton3871f6f2018-01-26 10:25:53 -0800933 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
934 StatsReports reports;
935 stats->GetStats(nullptr, &reports);
936
937 EXPECT_EQ(
938 rtc::ToString(kBytesSent),
939 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent));
940 EXPECT_EQ(rtc::ToString(kSendBandwidth),
941 ExtractBweStatsValue(
942 reports, StatsReport::kStatsValueNameAvailableSendBandwidth));
943 EXPECT_EQ(
944 rtc::ToString(kRecvBandwidth),
945 ExtractBweStatsValue(
946 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth));
947 EXPECT_EQ(
948 rtc::ToString(kPacerDelay),
949 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000950}
951
952// This test verifies that an object of type "googSession" always
953// exists in the returned stats.
954TEST_F(StatsCollectorTest, SessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800955 auto pc = CreatePeerConnection();
956 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000957
Steve Anton3871f6f2018-01-26 10:25:53 -0800958 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
959 StatsReports reports;
960 stats->GetStats(nullptr, &reports);
961
962 EXPECT_TRUE(
963 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000964}
965
966// This test verifies that only one object of type "googSession" exists
967// in the returned stats.
968TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800969 auto pc = CreatePeerConnection();
970 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000971
Steve Anton3871f6f2018-01-26 10:25:53 -0800972 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
973 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
974 StatsReports reports;
975 stats->GetStats(nullptr, &reports);
976
977 EXPECT_TRUE(
978 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 1));
979 EXPECT_FALSE(
980 FindNthReportByType(reports, StatsReport::kStatsReportTypeSession, 2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981}
982
983// This test verifies that the empty track report exists in the returned stats
984// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +0100985TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -0800986 auto pc = CreatePeerConnection();
987 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000988
Steve Anton5b387312018-02-02 16:00:20 -0800989 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -0800990 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000993 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -0800994 stats->GetStats(nullptr, &reports);
995 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000996 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -0700997 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998
999 std::string trackValue =
Yves Gerey665174f2018-06-19 15:03:05 +02001000 ExtractStatsValue(StatsReport::kStatsReportTypeTrack, reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001001 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001002 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001003}
1004
1005// This test verifies that the empty track report exists in the returned stats
1006// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001007TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001008 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001009
Steve Anton3871f6f2018-01-26 10:25:53 -08001010 auto pc = CreatePeerConnection();
1011 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001012
Steve Anton3871f6f2018-01-26 10:25:53 -08001013 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001014 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001016 VideoMediaInfo video_info;
1017 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001018
1019 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1020 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001021
Steve Anton3871f6f2018-01-26 10:25:53 -08001022 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023
Steve Anton3871f6f2018-01-26 10:25:53 -08001024 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001025 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001026 stats->GetStats(nullptr, &reports);
1027
wu@webrtc.org97077a32013-10-25 21:18:33 +00001028 // |reports| should contain at least one session report, one track report,
1029 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001030 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001031 const StatsReport* track_report =
1032 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001033 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001035 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001036 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001037 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001038 // |reports| should contain at least one session report, one track report,
1039 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001040 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001041 track_report =
1042 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001043 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001044 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045
Yves Gerey665174f2018-06-19 15:03:05 +02001046 std::string ssrc_id =
1047 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001048 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001049
Yves Gerey665174f2018-06-19 15:03:05 +02001050 std::string track_id =
1051 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001052 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001053
Yves Gerey665174f2018-06-19 15:03:05 +02001054 std::string media_type =
1055 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 01:27:15 -08001056 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057}
1058
1059// This test verifies that an SSRC object has the identifier of a Transport
1060// stats object, and that this transport stats object exists in stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001061TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001062 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001063
Steve Anton3871f6f2018-01-26 10:25:53 -08001064 auto pc = CreatePeerConnection();
1065 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001066
Steve Anton3871f6f2018-01-26 10:25:53 -08001067 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001068 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001069 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 10:25:53 -08001070 VideoMediaInfo video_info;
1071 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001072
1073 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1074 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001075
Steve Anton3871f6f2018-01-26 10:25:53 -08001076 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001077
Steve Anton3871f6f2018-01-26 10:25:53 -08001078 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001079 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001080 stats->GetStats(nullptr, &reports);
1081
Yves Gerey665174f2018-06-19 15:03:05 +02001082 std::string transport_id =
1083 ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports,
1084 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001086
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001087 // Transport id component ID will always be 1.
1088 // This has assumptions about how the ID is constructed. As is, this is
1089 // OK since this is for testing purposes only, but if we ever need this
1090 // in production, we should add a generic method that does this.
1091 size_t index = transport_id.find('-');
1092 ASSERT_NE(std::string::npos, index);
1093 std::string content = transport_id.substr(index + 1);
1094 index = content.rfind('-');
1095 ASSERT_NE(std::string::npos, index);
1096 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001097 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001098 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001099 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 10:25:53 -08001100 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001101}
1102
wu@webrtc.org97077a32013-10-25 21:18:33 +00001103// This test verifies that a remote stats object will not be created for
1104// an outgoing SSRC where remote stats are not returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001105TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001106 auto pc = CreatePeerConnection();
1107 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001108
Steve Anton5b387312018-02-02 16:00:20 -08001109 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 10:25:53 -08001110 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001111
Steve Anton3871f6f2018-01-26 10:25:53 -08001112 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001113 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001114 stats->GetStats(nullptr, &reports);
1115
Yves Gerey665174f2018-06-19 15:03:05 +02001116 const StatsReport* remote_report =
1117 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001118 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001119}
1120
1121// This test verifies that a remote stats object will be created for
1122// an outgoing SSRC where stats are returned.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001123TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001124 auto pc = CreatePeerConnection();
1125 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001126
Steve Anton3871f6f2018-01-26 10:25:53 -08001127 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001128 remote_ssrc_stats.timestamp = 12345.678;
1129 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 10:25:53 -08001130 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001131 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001132 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 10:25:53 -08001133 VideoMediaInfo video_info;
1134 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001135
1136 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1137 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001138
Steve Anton3871f6f2018-01-26 10:25:53 -08001139 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001140
Steve Anton3871f6f2018-01-26 10:25:53 -08001141 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001142 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001143 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001144
Yves Gerey665174f2018-06-19 15:03:05 +02001145 const StatsReport* remote_report =
1146 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001147 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001148 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001149}
1150
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001151// This test verifies that the empty track report exists in the returned stats
1152// when StatsCollector::UpdateStats is called with ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001153TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001154 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001155
Steve Anton3871f6f2018-01-26 10:25:53 -08001156 auto pc = CreatePeerConnection();
1157 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 11:50:27 -07001158
Steve Anton3871f6f2018-01-26 10:25:53 -08001159 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001160 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001161 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 10:25:53 -08001162 VideoMediaInfo video_info;
1163 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001164
1165 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1166 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001167
Steve Anton3871f6f2018-01-26 10:25:53 -08001168 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001169
Steve Anton3871f6f2018-01-26 10:25:53 -08001170 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001171 StatsReports reports;
Steve Anton3871f6f2018-01-26 10:25:53 -08001172 stats->GetStats(nullptr, &reports);
1173
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001174 // |reports| should contain at least one session report, one track report,
1175 // and one ssrc report.
Steve Anton3871f6f2018-01-26 10:25:53 -08001176 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 15:03:05 +02001177 const StatsReport* track_report =
1178 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001179 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001180 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001181
Yves Gerey665174f2018-06-19 15:03:05 +02001182 std::string ssrc_id =
1183 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001184 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001185
Yves Gerey665174f2018-06-19 15:03:05 +02001186 std::string track_id =
1187 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001188 EXPECT_EQ(kRemoteTrackId, track_id);
1189}
1190
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001191// This test verifies the Ice Candidate report should contain the correct
1192// information from local/remote candidates.
1193TEST_F(StatsCollectorTest, IceCandidateReport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001194 const std::string kTransportName = "transport";
1195 const rtc::AdapterType kNetworkType = rtc::ADAPTER_TYPE_ETHERNET;
1196 constexpr uint32_t kPriority = 1000;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001197
Steve Anton3871f6f2018-01-26 10:25:53 -08001198 constexpr int kLocalPort = 2000;
1199 const std::string kLocalIp = "192.168.0.1";
1200 const rtc::SocketAddress kLocalAddress(kLocalIp, kLocalPort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001201
Steve Anton3871f6f2018-01-26 10:25:53 -08001202 constexpr int kRemotePort = 2001;
1203 const std::string kRemoteIp = "192.168.0.2";
1204 const rtc::SocketAddress kRemoteAddress(kRemoteIp, kRemotePort);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001205
Steve Anton3871f6f2018-01-26 10:25:53 -08001206 auto pc = CreatePeerConnection();
1207 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001208
Steve Anton3871f6f2018-01-26 10:25:53 -08001209 cricket::Candidate local;
1210 EXPECT_GT(local.id().length(), 0u);
1211 local.set_type(cricket::LOCAL_PORT_TYPE);
1212 local.set_protocol(cricket::UDP_PROTOCOL_NAME);
1213 local.set_address(kLocalAddress);
1214 local.set_priority(kPriority);
1215 local.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001216
Steve Anton3871f6f2018-01-26 10:25:53 -08001217 cricket::Candidate remote;
1218 EXPECT_GT(remote.id().length(), 0u);
1219 remote.set_type(cricket::PRFLX_PORT_TYPE);
1220 remote.set_protocol(cricket::UDP_PROTOCOL_NAME);
1221 remote.set_address(kRemoteAddress);
1222 remote.set_priority(kPriority);
1223 remote.set_network_type(kNetworkType);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001224
Steve Anton3871f6f2018-01-26 10:25:53 -08001225 ConnectionInfo connection_info;
1226 connection_info.local_candidate = local;
1227 connection_info.remote_candidate = remote;
1228 TransportChannelStats channel_stats;
1229 channel_stats.connection_infos.push_back(connection_info);
1230
Steve Anton5b387312018-02-02 16:00:20 -08001231 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 10:25:53 -08001232 pc->SetTransportStats(kTransportName, channel_stats);
1233
1234 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1235 StatsReports reports;
1236 stats->GetStats(nullptr, &reports);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001237
1238 // Verify the local candidate report is populated correctly.
1239 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001240 "Cand-" + local.id(),
1241 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1242 StatsReport::kStatsValueNameLocalCandidateId));
1243 EXPECT_EQ(
1244 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001245 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1246 StatsReport::kStatsValueNameCandidateIPAddress));
1247 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001248 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001249 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1250 StatsReport::kStatsValueNameCandidatePortNumber));
1251 EXPECT_EQ(
1252 cricket::UDP_PROTOCOL_NAME,
1253 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1254 StatsReport::kStatsValueNameCandidateTransportType));
1255 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001256 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001257 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1258 StatsReport::kStatsValueNameCandidatePriority));
1259 EXPECT_EQ(
1260 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1261 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1262 StatsReport::kStatsValueNameCandidateType));
1263 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 10:25:53 -08001264 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001265 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1266 StatsReport::kStatsValueNameCandidateNetworkType));
1267
1268 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 10:25:53 -08001269 EXPECT_EQ(
1270 "Cand-" + remote.id(),
1271 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1272 StatsReport::kStatsValueNameRemoteCandidateId));
1273 EXPECT_EQ(kRemoteIp,
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001274 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1275 reports,
1276 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 10:25:53 -08001277 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001278 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1279 reports,
1280 StatsReport::kStatsValueNameCandidatePortNumber));
1281 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1282 ExtractStatsValue(
1283 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1284 StatsReport::kStatsValueNameCandidateTransportType));
Steve Anton3871f6f2018-01-26 10:25:53 -08001285 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001286 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1287 reports,
1288 StatsReport::kStatsValueNameCandidatePriority));
1289 EXPECT_EQ(
1290 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1291 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1292 reports, StatsReport::kStatsValueNameCandidateType));
1293 EXPECT_EQ(kNotFound,
1294 ExtractStatsValue(
1295 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1296 StatsReport::kStatsValueNameCandidateNetworkType));
1297}
1298
wu@webrtc.org4551b792013-10-09 15:37:36 +00001299// This test verifies that all chained certificates are correctly
1300// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001301TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001302 // Build local certificate chain.
1303 std::vector<std::string> local_ders(5);
1304 local_ders[0] = "These";
1305 local_ders[1] = "are";
1306 local_ders[2] = "some";
1307 local_ders[3] = "der";
1308 local_ders[4] = "values";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001309 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001310
1311 // Build remote certificate chain
1312 std::vector<std::string> remote_ders(4);
1313 remote_ders[0] = "A";
1314 remote_ders[1] = "non-";
1315 remote_ders[2] = "intersecting";
1316 remote_ders[3] = "set";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001317 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001318
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001319 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001320 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001321}
1322
1323// This test verifies that all certificates without chains are correctly
1324// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001325TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001326 // Build local certificate.
1327 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001328 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001329
1330 // Build remote certificate.
1331 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001332 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001333
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001334 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1335 remote_identity,
kwibergb4d01c42016-04-06 05:15:06 -07001336 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001337}
1338
1339// This test verifies that the stats are generated correctly when no
1340// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001341TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001342 auto pc = CreatePeerConnection();
1343 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001344
Steve Anton3871f6f2018-01-26 10:25:53 -08001345 // This will cause the fake PeerConnection to generate a TransportStats entry
1346 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-02 16:00:20 -08001347 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 11:50:27 -07001348
Steve Anton3871f6f2018-01-26 10:25:53 -08001349 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1350 StatsReports reports;
1351 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001352
1353 // Check that the local certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001354 std::string local_certificate_id =
1355 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1356 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001357 ASSERT_EQ(kNotFound, local_certificate_id);
1358
1359 // Check that the remote certificate is absent.
Yves Gerey665174f2018-06-19 15:03:05 +02001360 std::string remote_certificate_id =
1361 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1362 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001363 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001364
1365 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001366 std::string dtls_cipher_suite =
1367 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1368 StatsReport::kStatsValueNameDtlsCipher);
1369 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1370 std::string srtp_crypto_suite =
1371 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1372 StatsReport::kStatsValueNameSrtpCipher);
1373 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001374}
1375
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001376// This test verifies that a remote certificate with an unsupported digest
1377// algorithm is correctly ignored.
1378TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1379 // Build a local certificate.
1380 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001381 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001382
1383 // Build a remote certificate with an unsupported digest algorithm.
1384 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001385 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
1386 remote_cert.set_digest_algorithm("foobar");
1387 rtc::FakeSSLIdentity remote_identity(remote_cert);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001388
Taylor Brandstetterc3928662018-02-23 13:04:51 -08001389 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1390 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001391}
1392
zhihuang6ba3b192016-05-13 11:46:35 -07001393// This test verifies that the audio/video related stats which are -1 initially
1394// will be filtered out.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001395TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001396 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 10:25:53 -08001397 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001398 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001399 }
zhihuang6ba3b192016-05-13 11:46:35 -07001400
Steve Anton3871f6f2018-01-26 10:25:53 -08001401 auto pc = CreatePeerConnection();
1402 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 11:46:35 -07001403
1404 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 11:34:10 -08001405 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 11:46:35 -07001406 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1407 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1408 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001409 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001410 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001411 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001412 }
Steve Anton3871f6f2018-01-26 10:25:53 -08001413 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 11:46:35 -07001414
1415 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001416 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001417 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 11:46:35 -07001418 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1419 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 11:46:35 -07001420 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001421 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001422 if (GetParam()) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001423 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001424 }
zhihuang6ba3b192016-05-13 11:46:35 -07001425
Steve Anton3871f6f2018-01-26 10:25:53 -08001426 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001427 voice_sender_info.add_ssrc(kSsrcOfTrack);
1428 // These values are set to -1 initially in audio_send_stream.
1429 // The voice_sender_info will read the values from audio_send_stream.
1430 voice_sender_info.rtt_ms = -1;
1431 voice_sender_info.packets_lost = -1;
1432 voice_sender_info.jitter_ms = -1;
1433
1434 // Some of the contents in |voice_sender_info| needs to be updated from the
1435 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001436 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1437 true);
zhihuang6ba3b192016-05-13 11:46:35 -07001438
Steve Anton3871f6f2018-01-26 10:25:53 -08001439 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 11:46:35 -07001440 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1441 voice_receiver_info.capture_start_ntp_time_ms = -1;
1442 voice_receiver_info.audio_level = -1;
1443
1444 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001445 VoiceMediaInfo voice_info;
1446 voice_info.senders.push_back(voice_sender_info);
1447 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001448
Steve Anton5b387312018-02-02 16:00:20 -08001449 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1450 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 11:46:35 -07001451
Steve Anton3871f6f2018-01-26 10:25:53 -08001452 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 11:46:35 -07001453
1454 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001455 StatsReports reports;
1456 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001457 const StatsReport* report =
1458 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001459 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001460 // The -1 will not be added to the stats report.
1461 std::string value_in_report;
1462 EXPECT_FALSE(
1463 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1464 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1465 &value_in_report));
1466 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1467 &value_in_report));
zhihuang6ba3b192016-05-13 11:46:35 -07001468 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1469 &value_in_report));
1470 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1471 &value_in_report));
1472
1473 // Get stats for the remote track.
1474 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001475 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 11:46:35 -07001476 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001477 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 11:46:35 -07001478 EXPECT_FALSE(GetValue(report,
1479 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1480 &value_in_report));
1481 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1482 &value_in_report));
1483}
1484
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001485// This test verifies that a local stats object can get statistics via
1486// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001487TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001488 auto pc = CreatePeerConnection();
1489 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001490
Steve Anton3871f6f2018-01-26 10:25:53 -08001491 AddOutgoingAudioTrack(pc, stats.get());
1492 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001493
Steve Anton3871f6f2018-01-26 10:25:53 -08001494 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001495 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001496 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1497 VoiceMediaInfo voice_info;
1498 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001499
1500 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1501 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001502
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001503 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001504 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001505
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001506 // Verify that there is no remote report for the local audio track because
1507 // we did not set it up.
Yves Gerey665174f2018-06-19 15:03:05 +02001508 const StatsReport* remote_report =
1509 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001510 EXPECT_TRUE(remote_report == NULL);
1511}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001512
1513// This test verifies that audio receive streams populate stats reports
1514// correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001515TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001516 auto pc = CreatePeerConnection();
1517 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001518
Steve Anton3871f6f2018-01-26 10:25:53 -08001519 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 11:50:27 -07001520
Steve Anton3871f6f2018-01-26 10:25:53 -08001521 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001522 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001523 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 10:25:53 -08001524 VoiceMediaInfo voice_info;
1525 voice_info.receivers.push_back(voice_receiver_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);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001529
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001530 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001531 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001532}
1533
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001534// This test verifies that a local stats object won't update its statistics
1535// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001536TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001537 auto pc = CreatePeerConnection();
1538 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001539
Steve Anton3871f6f2018-01-26 10:25:53 -08001540 AddOutgoingAudioTrack(pc, stats.get());
1541 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 11:50:27 -07001542
Steve Anton3871f6f2018-01-26 10:25:53 -08001543 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001544 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001545 VoiceMediaInfo voice_info;
1546 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001547
Steve Anton5b387312018-02-02 16:00:20 -08001548 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1549 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001550
Steve Anton3871f6f2018-01-26 10:25:53 -08001551 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001552
Steve Anton3871f6f2018-01-26 10:25:53 -08001553 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1554 StatsReports reports;
1555 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001556
1557 // The report will exist since we don't remove them in RemoveStream().
Yves Gerey665174f2018-06-19 15:03:05 +02001558 const StatsReport* report =
1559 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 10:25:53 -08001560 ASSERT_TRUE(report);
1561 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001562 std::string track_id =
1563 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001564 EXPECT_EQ(kLocalTrackId, track_id);
Yves Gerey665174f2018-06-19 15:03:05 +02001565 std::string ssrc_id =
1566 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 11:59:48 +02001567 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001568
1569 // Verifies the values in the track report, no value will be changed by the
1570 // AudioTrackInterface::GetSignalValue() and
Sam Zackrisson28127632018-11-01 11:37:15 +01001571 // AudioProcessorInterface::GetStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001572 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1573}
1574
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001575// This test verifies that when ongoing and incoming audio tracks are using
1576// the same ssrc, they populate stats reports correctly.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001577TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001578 auto pc = CreatePeerConnection();
1579 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001580
1581 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001582 AddOutgoingAudioTrack(pc, stats.get());
1583 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001584
1585 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001586 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 11:34:10 -08001587 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001588 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1589 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001590 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001591 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 10:25:53 -08001592 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001593
Steve Anton3871f6f2018-01-26 10:25:53 -08001594 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001595 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001596 // Some of the contents in |voice_sender_info| needs to be updated from the
1597 // |audio_track_|.
Ivo Creusen56d46092017-11-24 17:29:59 +01001598 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1599 true);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001600
Steve Anton3871f6f2018-01-26 10:25:53 -08001601 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001602 InitVoiceReceiverInfo(&voice_receiver_info);
1603
1604 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 10:25:53 -08001605 VoiceMediaInfo voice_info;
1606 voice_info.senders.push_back(voice_sender_info);
1607 voice_info.receivers.push_back(voice_receiver_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001608
Steve Anton3871f6f2018-01-26 10:25:53 -08001609 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-02 16:00:20 -08001610 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1611 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001612
Steve Anton3871f6f2018-01-26 10:25:53 -08001613 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001614
1615 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 10:25:53 -08001616 StatsReports reports; // returned values.
1617 stats->GetStats(audio_track_.get(), &reports);
1618
Yves Gerey665174f2018-06-19 15:03:05 +02001619 const StatsReport* track_report =
1620 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001621 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001622 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001623 std::string track_id =
1624 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001625 EXPECT_EQ(kLocalTrackId, track_id);
1626 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1627
1628 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001629 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001630 stats->GetStats(remote_track.get(), &reports);
Yves Gerey665174f2018-06-19 15:03:05 +02001631 track_report =
1632 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001633 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 10:25:53 -08001634 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 15:03:05 +02001635 track_id =
1636 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001637 EXPECT_EQ(kRemoteTrackId, track_id);
1638 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1639}
1640
xians@webrtc.org01bda202014-07-09 07:38:38 +00001641// This test verifies that when two outgoing audio tracks are using the same
1642// ssrc at different times, they populate stats reports correctly.
1643// TODO(xians): Figure out if it is possible to encapsulate the setup and
1644// avoid duplication of code in test cases.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001645TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001646 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 10:25:53 -08001647 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001648 return;
Steve Anton3871f6f2018-01-26 10:25:53 -08001649 }
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001650
Steve Anton3871f6f2018-01-26 10:25:53 -08001651 auto pc = CreatePeerConnection();
1652 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001653
1654 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001655 AddOutgoingAudioTrack(pc, stats.get());
1656 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001657
Steve Anton3871f6f2018-01-26 10:25:53 -08001658 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 08:13:19 -07001659 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001660 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001661 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 10:25:53 -08001662 VoiceMediaInfo voice_info;
1663 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001664
1665 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1666 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001667
xians@webrtc.org01bda202014-07-09 07:38:38 +00001668 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 10:25:53 -08001669 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001670
1671 // Remove the previous audio track from the stream.
1672 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 10:25:53 -08001673 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001674
1675 // Create a new audio track and adds it to the stream and stats.
1676 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001677 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1678 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 10:25:53 -08001679 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001680 stream_->AddTrack(new_audio_track);
1681
Steve Anton3871f6f2018-01-26 10:25:53 -08001682 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1683 stats->ClearUpdateStatsCacheForTest();
1684
1685 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:38 +00001686 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001687 UpdateVoiceSenderInfoFromAudioTrack(new_audio_track, &new_voice_sender_info,
1688 false);
1689 VoiceMediaInfo new_voice_info;
1690 new_voice_info.senders.push_back(new_voice_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001691 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 10:25:53 -08001692
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001693 reports.clear();
Steve Anton3871f6f2018-01-26 10:25:53 -08001694 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001695}
1696
sakal43536c32016-10-24 01:46:43 -07001697// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001698TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 10:25:53 -08001699 auto pc = CreatePeerConnection();
1700 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 01:46:43 -07001701
Steve Anton3871f6f2018-01-26 10:25:53 -08001702 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 01:46:43 -07001703
Steve Anton3871f6f2018-01-26 10:25:53 -08001704 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 01:46:43 -07001705 video_sender_info.add_ssrc(1234);
1706 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +01001707 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001708 VideoMediaInfo video_info;
1709 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-02 16:00:20 -08001710
1711 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1712 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 01:46:43 -07001713
Steve Anton3871f6f2018-01-26 10:25:53 -08001714 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1715 StatsReports reports;
1716 stats->GetStats(nullptr, &reports);
1717
sakal43536c32016-10-24 01:46:43 -07001718 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1719 ExtractSsrcStatsValue(reports,
1720 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07001721 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1722 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07001723}
1724
sakale5ba44e2016-10-26 07:09:24 -07001725// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 10:25:53 -08001726TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1727 auto pc = CreatePeerConnection();
1728 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 07:09:24 -07001729
Steve Anton3871f6f2018-01-26 10:25:53 -08001730 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 07:09:24 -07001731
Steve Anton3871f6f2018-01-26 10:25:53 -08001732 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 07:09:24 -07001733 video_receiver_info.add_ssrc(1234);
1734 video_receiver_info.frames_decoded = 10;
Artem Titov8a3ab0e2018-07-27 14:52:57 +00001735 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 10:25:53 -08001736 VideoMediaInfo video_info;
1737 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-02 16:00:20 -08001738
1739 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1740 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 07:09:24 -07001741
Steve Anton3871f6f2018-01-26 10:25:53 -08001742 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1743 StatsReports reports;
1744 stats->GetStats(nullptr, &reports);
1745
sakale5ba44e2016-10-26 07:09:24 -07001746 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1747 ExtractSsrcStatsValue(reports,
1748 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08001749 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1750 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07001751}
1752
Harald Alvestrand75ceef22018-01-04 15:26:13 +01001753INSTANTIATE_TEST_CASE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
1754
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001755} // namespace webrtc