blob: eed30ef1d16aafb420566d65f62be3fb998d11d8 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellanderb24317b2016-02-10 15:54:432 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellanderb24317b2016-02-10 15:54:434 * 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:369 */
10
11#include <stdio.h>
jbauch555604a2016-04-26 10:13:2212#include <memory>
deadbeefcbecd352015-09-23 18:50:2713
Steve Anton64b626b2019-01-29 01:25:2614#include "absl/algorithm/container.h"
Yves Gerey3e707812018-11-28 15:47:4915#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 17:11:0019#include "api/data_channel_interface.h"
Mirko Bonadeid9708072019-01-25 19:26:4820#include "api/scoped_refptr.h"
Yves Gerey3e707812018-11-28 15:47:4921#include "call/call.h"
Steve Anton10542f22019-01-11 17:11:0022#include "media/base/media_channel.h"
Yves Gerey3e707812018-11-28 15:47:4923#include "modules/audio_processing/include/audio_processing_statistics.h"
Steve Anton10542f22019-01-11 17:11:0024#include "pc/data_channel.h"
25#include "pc/media_stream.h"
26#include "pc/media_stream_track.h"
27#include "pc/stats_collector.h"
28#include "pc/test/fake_peer_connection_for_stats.h"
29#include "pc/test/fake_video_track_source.h"
30#include "pc/transport_stats.h"
31#include "pc/video_track.h"
32#include "rtc_base/fake_ssl_identity.h"
33#include "rtc_base/message_digest.h"
34#include "rtc_base/net_helper.h"
35#include "rtc_base/ref_counted_object.h"
36#include "rtc_base/rtc_certificate.h"
Steve Anton10542f22019-01-11 17:11:0037#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 15:38:1241#include "rtc_base/third_party/base64/base64.h"
Yves Gerey3e707812018-11-28 15:47:4942#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3143#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:3644
Steve Anton3871f6f2018-01-26 18:25:5345using 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:3654
guoweis@webrtc.org950c5182014-12-16 23:01:3155namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:3656
tkchin7d06a8c2016-04-04 21:10:4357namespace 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:3662// Error return values
63const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:3664
wu@webrtc.org97077a32013-10-25 21:18:3365// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:0566const char kLocalTrackId[] = "local_track_id";
67const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 10:23:2168const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:3369
Steve Anton3871f6f2018-01-26 18:25:5370class FakeAudioProcessor : public AudioProcessorInterface {
henrike@webrtc.org40b3b682014-03-03 18:30:1171 public:
72 FakeAudioProcessor() {}
73 ~FakeAudioProcessor() {}
74
75 private:
Ivo Creusenae0260962017-11-20 12:07:1676 AudioProcessorInterface::AudioProcessorStatistics GetStats(
Ivo Creusen56d460902017-11-24 16:29:5977 bool has_recv_streams) override {
Ivo Creusenae0260962017-11-20 12:07:1678 AudioProcessorStatistics stats;
79 stats.typing_noise_detected = true;
Ivo Creusen56d460902017-11-24 16:29:5980 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 Creusenae0260962017-11-20 12:07:1686 return stats;
87 }
henrike@webrtc.org40b3b682014-03-03 18:30:1188};
89
Steve Anton3871f6f2018-01-26 18:25:5390class FakeAudioTrack : public MediaStreamTrack<AudioTrackInterface> {
henrike@webrtc.org40b3b682014-03-03 18:30:1191 public:
xians@webrtc.org4cb01282014-06-12 14:57:0592 explicit FakeAudioTrack(const std::string& id)
Steve Anton3871f6f2018-01-26 18:25:5393 : MediaStreamTrack<AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5294 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:3595 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 18:25:5396 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:3599 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11100 *level = 1;
101 return true;
102 }
Steve Anton3871f6f2018-01-26 18:25:53103 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57104 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11105 }
106
107 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52108 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11109};
110
zhihuang6ba3b192016-05-13 18:46:35111// This fake audio processor is used to verify that the undesired initial values
112// (-1) will be filtered out.
Steve Anton3871f6f2018-01-26 18:25:53113class FakeAudioProcessorWithInitValue : public AudioProcessorInterface {
zhihuang6ba3b192016-05-13 18:46:35114 public:
115 FakeAudioProcessorWithInitValue() {}
116 ~FakeAudioProcessorWithInitValue() {}
117
118 private:
Ivo Creusenae0260962017-11-20 12:07:16119 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 18:46:35125};
126
127class FakeAudioTrackWithInitValue
Steve Anton3871f6f2018-01-26 18:25:53128 : public MediaStreamTrack<AudioTrackInterface> {
zhihuang6ba3b192016-05-13 18:46:35129 public:
130 explicit FakeAudioTrackWithInitValue(const std::string& id)
Steve Anton3871f6f2018-01-26 18:25:53131 : MediaStreamTrack<AudioTrackInterface>(id),
zhihuang6ba3b192016-05-13 18:46:35132 processor_(
133 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
134 std::string kind() const override { return "audio"; }
Steve Anton3871f6f2018-01-26 18:25:53135 AudioSourceInterface* GetSource() const override { return NULL; }
136 void AddSink(AudioTrackSinkInterface* sink) override {}
137 void RemoveSink(AudioTrackSinkInterface* sink) override {}
zhihuang6ba3b192016-05-13 18:46:35138 bool GetSignalLevel(int* level) override {
139 *level = 1;
140 return true;
141 }
Steve Anton3871f6f2018-01-26 18:25:53142 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
zhihuang6ba3b192016-05-13 18:46:35143 return processor_;
144 }
145
146 private:
147 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
148};
149
henrike@webrtc.org40b3b682014-03-03 18:30:11150bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56151 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36152 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19153 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:36158}
159
tommi@webrtc.org4fb7e252015-01-21 11:36:18160std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11161 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56162 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18163 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36164 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18165 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36166 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36167 }
168
169 return kNotFound;
170}
171
tommi@webrtc.orgd3900292015-03-12 16:35:55172StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
173 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18174 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55175 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18176 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55177 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18178
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:55185 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18186
187 id = StatsReport::NewTypedId(type, value.substr(index + 1));
188 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55189 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18190}
191
tommi@webrtc.orgd3900292015-03-12 16:35:55192StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
193 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18194}
195
henrike@webrtc.org28e20752013-07-10 00:45:36196// Finds the |n|-th report of type |type| in |reports|.
197// |n| starts from 1 for finding the first report.
Yves Gerey665174f2018-06-19 13:03:05198const StatsReport* FindNthReportByType(const StatsReports& reports,
199 const StatsReport::StatsType& type,
200 int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36201 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18202 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36203 n--;
204 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30205 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36206 }
207 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18208 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36209}
210
henrike@webrtc.org40b3b682014-03-03 18:30:11211const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18212 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26213 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55214 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26215 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36216 }
tommi@webrtc.org8e327c42015-01-19 20:41:26217 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36218}
219
Mirko Bonadeic61ce0d2017-11-21 16:04:20220std::string ExtractSsrcStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56221 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18222 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36223}
224
Mirko Bonadeic61ce0d2017-11-21 16:04:20225std::string ExtractBweStatsValue(const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56226 StatsReport::StatsValueName name) {
Yves Gerey665174f2018-06-19 13:03:05227 return ExtractStatsValue(StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36228}
229
wu@webrtc.org4551b792013-10-09 15:37:36230std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52231 return rtc::SSLIdentity::DerToPem(
Yves Gerey665174f2018-06-19 13:03:05232 rtc::kPemTypeCertificate,
233 reinterpret_cast<const unsigned char*>(der.c_str()), der.length());
wu@webrtc.org4551b792013-10-09 15:37:36234}
235
Yves Gerey665174f2018-06-19 13:03:05236std::vector<std::string> DersToPems(const std::vector<std::string>& ders) {
wu@webrtc.org4551b792013-10-09 15:37:36237 std::vector<std::string> pems(ders.size());
Steve Anton64b626b2019-01-29 01:25:26238 absl::c_transform(ders, pems.begin(), DerToPem);
wu@webrtc.org4551b792013-10-09 15:37:36239 return pems;
240}
241
henrike@webrtc.org40b3b682014-03-03 18:30:11242void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36243 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18244 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55245 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18246 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36247 size_t i = 0;
248 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18249 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36250 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27251
wu@webrtc.org4551b792013-10-09 15:37:36252 std::string der_base64;
Yves Gerey665174f2018-06-19 13:03:05253 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18254 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36255 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27256
257 std::string fingerprint_algorithm;
Yves Gerey665174f2018-06-19 13:03:05258 EXPECT_TRUE(GetValue(report,
259 StatsReport::kStatsValueNameFingerprintAlgorithm,
260 &fingerprint_algorithm));
mallinath@webrtc.org19f27e62013-10-13 17:18:27261 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52262 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27263 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
264
tommi@webrtc.org4fb7e252015-01-21 11:36:18265 std::string fingerprint;
266 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
267 &fingerprint));
268 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27269
wu@webrtc.org4551b792013-10-09 15:37:36270 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18271 std::string issuer_id;
Yves Gerey665174f2018-06-19 13:03:05272 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId, &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36273 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18274 }
275
tommi@webrtc.orgd3900292015-03-12 16:35:55276 cert_id = IdFromCertIdString(issuer_id);
277 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36278 }
279 EXPECT_EQ(ders.size(), i);
280}
281
Yves Gerey665174f2018-06-19 13:03:05282void VerifyVoiceReceiverInfoReport(const StatsReport* report,
283 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10284 std::string value_in_report;
Yves Gerey665174f2018-06-19 13:03:05285 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioOutputLevel,
286 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48287 EXPECT_EQ(rtc::ToString(info.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05288 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived,
289 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48290 EXPECT_EQ(rtc::ToString(info.bytes_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05291 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
292 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48293 EXPECT_EQ(rtc::ToString(info.jitter_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05294 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterBufferMs,
295 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48296 EXPECT_EQ(rtc::ToString(info.jitter_buffer_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05297 EXPECT_TRUE(GetValue(report,
298 StatsReport::kStatsValueNamePreferredJitterBufferMs,
299 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48300 EXPECT_EQ(rtc::ToString(info.jitter_buffer_preferred_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05301 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCurrentDelayMs,
302 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48303 EXPECT_EQ(rtc::ToString(info.delay_estimate_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05304 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameExpandRate,
305 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48306 EXPECT_EQ(rtc::ToString(info.expand_rate), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05307 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSpeechExpandRate,
308 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48309 EXPECT_EQ(rtc::ToString(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 07:24:52310 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
311 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48312 EXPECT_EQ(rtc::ToString(info.accelerate_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 07:24:52313 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
314 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48315 EXPECT_EQ(rtc::ToString(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46316 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
317 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48318 EXPECT_EQ(rtc::ToString(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 11:51:27319 EXPECT_TRUE(GetValue(report,
320 StatsReport::kStatsValueNameSecondaryDiscardedRate,
321 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48322 EXPECT_EQ(rtc::ToString(info.secondary_discarded_rate), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05323 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived,
324 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48325 EXPECT_EQ(rtc::ToString(info.packets_rcvd), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05326 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG,
327 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48328 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_silence_generator),
Yves Gerey665174f2018-06-19 13:03:05329 value_in_report);
330 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTN,
331 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48332 EXPECT_EQ(rtc::ToString(info.decoding_calls_to_neteq), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05333 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingNormal,
334 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48335 EXPECT_EQ(rtc::ToString(info.decoding_normal), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05336 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLC,
337 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48338 EXPECT_EQ(rtc::ToString(info.decoding_plc), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05339 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCNG,
340 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48341 EXPECT_EQ(rtc::ToString(info.decoding_cng), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05342 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingPLCCNG,
343 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48344 EXPECT_EQ(rtc::ToString(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 08:47:12345 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
346 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48347 EXPECT_EQ(rtc::ToString(info.decoding_muted_output), value_in_report);
henrik.lundin63489782016-09-20 08:47:12348 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
349 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10350}
351
henrike@webrtc.org40b3b682014-03-03 18:30:11352void VerifyVoiceSenderInfoReport(const StatsReport* report,
353 const cricket::VoiceSenderInfo& sinfo) {
354 std::string value_in_report;
Yves Gerey665174f2018-06-19 13:03:05355 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
356 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11357 EXPECT_EQ(sinfo.codec_name, value_in_report);
Yves Gerey665174f2018-06-19 13:03:05358 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesSent,
359 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48360 EXPECT_EQ(rtc::ToString(sinfo.bytes_sent), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05361 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsSent,
362 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48363 EXPECT_EQ(rtc::ToString(sinfo.packets_sent), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05364 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
365 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48366 EXPECT_EQ(rtc::ToString(sinfo.packets_lost), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05367 EXPECT_TRUE(
368 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48369 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05370 EXPECT_TRUE(
371 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48372 EXPECT_EQ(rtc::ToString(sinfo.rtt_ms), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05373 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
374 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48375 EXPECT_EQ(rtc::ToString(sinfo.jitter_ms), value_in_report);
Ivo Creusen56d460902017-11-24 16:29:59376 if (sinfo.apm_statistics.delay_median_ms) {
377 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
378 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48379 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_median_ms),
Ivo Creusen56d460902017-11-24 16:29:59380 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 09:59:48388 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.delay_standard_deviation_ms),
389 value_in_report);
Ivo Creusen56d460902017-11-24 16:29:59390 } 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 09:59:48397 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss),
Ivo Creusen56d460902017-11-24 16:29:59398 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 09:59:48407 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.echo_return_loss_enhancement),
408 value_in_report);
Ivo Creusen56d460902017-11-24 16:29:59409 } 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 09:59:48418 EXPECT_EQ(rtc::ToString(*sinfo.apm_statistics.residual_echo_likelihood),
419 value_in_report);
Ivo Creusen56d460902017-11-24 16:29:59420 } 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 09:59:48429 EXPECT_EQ(rtc::ToString(
Ivo Creusen56d460902017-11-24 16:29:59430 *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 11:10:03437 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
438 &value_in_report));
Jonas Olsson6b1985d2018-07-05 09:59:48439 EXPECT_EQ(rtc::ToString(sinfo.audio_level), value_in_report);
Yves Gerey665174f2018-06-19 13:03:05440 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameTypingNoiseState,
441 &value_in_report));
henrike@webrtc.org40b3b682014-03-03 18:30:11442 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
443 EXPECT_EQ(typing_detected, value_in_report);
ivoce1198e02017-09-08 15:13:19444 EXPECT_TRUE(GetValue(report,
445 StatsReport::kStatsValueNameAnaBitrateActionCounter,
446 &value_in_report));
447 ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter);
Jonas Olsson6b1985d2018-07-05 09:59:48448 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.bitrate_action_counter),
449 value_in_report);
ivoce1198e02017-09-08 15:13:19450 EXPECT_TRUE(GetValue(report,
451 StatsReport::kStatsValueNameAnaChannelActionCounter,
452 &value_in_report));
453 ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter);
Jonas Olsson6b1985d2018-07-05 09:59:48454 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.channel_action_counter),
455 value_in_report);
ivoce1198e02017-09-08 15:13:19456 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter,
457 &value_in_report));
458 ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter);
Jonas Olsson6b1985d2018-07-05 09:59:48459 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.dtx_action_counter),
ivoce1198e02017-09-08 15:13:19460 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 09:59:48464 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.fec_action_counter),
ivoce1198e02017-09-08 15:13:19465 value_in_report);
ivoc0d0b9122017-09-08 20:24:21466 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 09:59:48470 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_increase_counter),
ivoce1198e02017-09-08 15:13:19471 value_in_report);
ivoc0d0b9122017-09-08 20:24:21472 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 09:59:48476 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.frame_length_decrease_counter),
ivoc0d0b9122017-09-08 20:24:21477 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 09:59:48482 EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.uplink_packet_loss_fraction),
483 value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11484}
485
xians@webrtc.org4cb01282014-06-12 14:57:05486// 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 12:51:24498 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:05502 voice_sender_info->typing_noise_detected = false;
Ivo Creusen56d460902017-11-24 16:29:59503 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:05510}
511
512void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 18:46:35513 AudioTrackInterface* audio_track,
Ivo Creusen56d460902017-11-24 16:29:59514 cricket::VoiceSenderInfo* voice_sender_info,
515 bool has_remote_tracks) {
xians@webrtc.org4cb01282014-06-12 14:57:05516 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
Steve Anton3871f6f2018-01-26 18:25:53517 AudioProcessorInterface::AudioProcessorStatistics audio_processor_stats =
518 audio_track->GetAudioProcessor()->GetStats(has_remote_tracks);
xians@webrtc.org4cb01282014-06-12 14:57:05519 voice_sender_info->typing_noise_detected =
520 audio_processor_stats.typing_noise_detected;
Ivo Creusen56d460902017-11-24 16:29:59521 voice_sender_info->apm_statistics = audio_processor_stats.apm_statistics;
xians@webrtc.org4cb01282014-06-12 14:57:05522}
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:46538 voice_receiver_info->speech_expand_rate = 122;
539 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 07:24:52540 voice_receiver_info->accelerate_rate = 124;
541 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 11:51:27542 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05543}
544
Steve Anton3871f6f2018-01-26 18:25:53545class StatsCollectorForTest : public StatsCollector {
decurtis@webrtc.org322a5642015-02-03 22:09:37546 public:
Steve Anton3871f6f2018-01-26 18:25:53547 explicit StatsCollectorForTest(PeerConnectionInternal* pc)
deadbeefab9b2d12015-10-14 18:33:11548 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37549
Yves Gerey665174f2018-06-19 13:03:05550 double GetTimeNow() override { return time_now_; }
decurtis@webrtc.org322a5642015-02-03 22:09:37551
552 private:
553 double time_now_;
554};
555
henrike@webrtc.org28e20752013-07-10 00:45:36556class StatsCollectorTest : public testing::Test {
557 protected:
Steve Anton3871f6f2018-01-26 18:25:53558 rtc::scoped_refptr<FakePeerConnectionForStats> CreatePeerConnection() {
559 return new rtc::RefCountedObject<FakePeerConnectionForStats>();
henrike@webrtc.org28e20752013-07-10 00:45:36560 }
561
Steve Anton3871f6f2018-01-26 18:25:53562 std::unique_ptr<StatsCollectorForTest> CreateStatsCollector(
563 PeerConnectionInternal* pc) {
Karl Wiberg918f50c2018-07-05 09:40:33564 return absl::make_unique<StatsCollectorForTest>(pc);
wu@webrtc.org97077a32013-10-25 21:18:33565 }
566
Steve Anton3871f6f2018-01-26 18:25:53567 void VerifyAudioTrackStats(FakeAudioTrack* audio_track,
568 StatsCollectorForTest* stats,
569 const VoiceMediaInfo& voice_info,
570 StatsReports* reports) {
xians@webrtc.org01bda202014-07-09 07:38:38571 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48572 stats->ClearUpdateStatsCacheForTest();
Steve Anton3871f6f2018-01-26 18:25:53573 stats->GetStats(nullptr, reports);
xians@webrtc.org01bda202014-07-09 07:38:38574
575 // Verify the existence of the track report.
Yves Gerey665174f2018-06-19 13:03:05576 const StatsReport* report =
577 FindNthReportByType(*reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 18:25:53578 ASSERT_TRUE(report);
jbauchbe24c942015-06-22 22:06:43579 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 13:03:05580 std::string track_id =
581 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org01bda202014-07-09 07:38:38582 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 13:03:05583 std::string ssrc_id =
584 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 09:59:48585 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38586
Yves Gerey665174f2018-06-19 13:03:05587 std::string media_type =
588 ExtractSsrcStatsValue(*reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 09:27:15589 EXPECT_EQ("audio", media_type);
590
xians@webrtc.org01bda202014-07-09 07:38:38591 // Verifies the values in the track report.
Steve Anton3871f6f2018-01-26 18:25:53592 if (!voice_info.senders.empty()) {
593 VerifyVoiceSenderInfoReport(report, voice_info.senders[0]);
xians@webrtc.org01bda202014-07-09 07:38:38594 }
Steve Anton3871f6f2018-01-26 18:25:53595 if (!voice_info.receivers.empty()) {
596 VerifyVoiceReceiverInfoReport(report, voice_info.receivers[0]);
xians@webrtc.org01bda202014-07-09 07:38:38597 }
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 18:25:53604 ASSERT_TRUE(track_report);
jbauchbe24c942015-06-22 22:06:43605 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38606 track_id = ExtractSsrcStatsValue(track_reports,
607 StatsReport::kStatsValueNameTrackId);
608 EXPECT_EQ(audio_track->id(), track_id);
Yves Gerey665174f2018-06-19 13:03:05609 ssrc_id =
610 ExtractSsrcStatsValue(track_reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 09:59:48611 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
Steve Anton3871f6f2018-01-26 18:25:53612 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:11618 }
619
Taylor Brandstetterc3928662018-02-23 21:04:51620 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 18:25:53624 const std::string kTransportName = "transport";
decurtis@webrtc.org487a4442015-01-15 22:55:07625
Steve Anton3871f6f2018-01-26 18:25:53626 auto pc = CreatePeerConnection();
627 auto stats = CreateStatsCollector(pc);
628
Steve Anton5b387312018-02-03 00:00:20629 pc->AddVoiceChannel("audio", kTransportName);
wu@webrtc.org4551b792013-10-09 15:37:36630
631 // Fake stats to process.
Steve Anton3871f6f2018-01-26 18:25:53632 TransportChannelStats channel_stats;
wu@webrtc.org4551b792013-10-09 15:37:36633 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-19 03:41:53634 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 21:10:43635 channel_stats.ssl_cipher_suite =
636 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
Steve Anton3871f6f2018-01-26 18:25:53637 pc->SetTransportStats(kTransportName, channel_stats);
wu@webrtc.org4551b792013-10-09 15:37:36638
Taylor Brandstetterc3928662018-02-23 21:04:51639 // Fake certificate to report.
Henrik Boströmd8281982015-08-27 08:12:24640 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
Steve Anton3871f6f2018-01-26 18:25:53641 rtc::RTCCertificate::Create(
Taylor Brandstetterc3928662018-02-23 21:04:51642 std::unique_ptr<rtc::SSLIdentity>(local_identity.GetReference())));
Steve Anton3871f6f2018-01-26 18:25:53643 pc->SetLocalCertificate(kTransportName, local_certificate);
Taylor Brandstetterc3928662018-02-23 21:04:51644 pc->SetRemoteCertChain(kTransportName,
Steve Antonf25303e2018-10-16 22:23:31645 remote_identity.cert_chain().Clone());
wu@webrtc.org4551b792013-10-09 15:37:36646
Steve Anton3871f6f2018-01-26 18:25:53647 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36648
Steve Anton3871f6f2018-01-26 18:25:53649 StatsReports reports;
650 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:36651
Yves Gerey665174f2018-06-19 13:03:05652 const StatsReport* channel_report =
653 FindNthReportByType(reports, StatsReport::kStatsReportTypeComponent, 1);
Steve Anton3871f6f2018-01-26 18:25:53654 EXPECT_TRUE(channel_report);
wu@webrtc.org4551b792013-10-09 15:37:36655
656 // Check local certificate chain.
Yves Gerey665174f2018-06-19 13:03:05657 std::string local_certificate_id =
658 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
659 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49660 if (local_ders.size() > 0) {
661 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55662 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
663 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49664 } else {
665 EXPECT_EQ(kNotFound, local_certificate_id);
666 }
wu@webrtc.org4551b792013-10-09 15:37:36667
668 // Check remote certificate chain.
Yves Gerey665174f2018-06-19 13:03:05669 std::string remote_certificate_id =
670 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
671 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49672 if (remote_ders.size() > 0) {
673 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55674 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
675 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49676 } else {
677 EXPECT_EQ(kNotFound, remote_certificate_id);
678 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30679
680 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-19 03:41:53681 std::string dtls_cipher_suite =
682 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
683 StatsReport::kStatsValueNameDtlsCipher);
684 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 21:10:43685 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-19 03:41:53686 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:36692 }
Harald Alvestrand75ceef22018-01-04 14:26:13693};
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 18:25:53701 void AddOutgoingVideoTrack(FakePeerConnectionForStats* pc,
702 StatsCollectorForTest* stats) {
703 track_ = VideoTrack::Create(kLocalTrackId, FakeVideoTrackSource::Create(),
704 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 14:26:13705 if (GetParam()) {
706 if (!stream_)
Seth Hampson845e8782018-03-02 19:34:10707 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 14:26:13708 stream_->AddTrack(track_);
709 stats->AddStream(stream_);
710 } else {
711 stats->AddTrack(track_);
712 }
Steve Anton3871f6f2018-01-26 18:25:53713 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:13714 }
715
716 // Adds a incoming video track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 18:25:53717 void AddIncomingVideoTrack(FakePeerConnectionForStats* pc,
718 StatsCollectorForTest* stats) {
719 track_ = VideoTrack::Create(kRemoteTrackId, FakeVideoTrackSource::Create(),
720 rtc::Thread::Current());
Harald Alvestrand75ceef22018-01-04 14:26:13721 if (GetParam()) {
Seth Hampson845e8782018-03-02 19:34:10722 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 14:26:13723 stream_->AddTrack(track_);
724 stats->AddStream(stream_);
725 } else {
726 stats->AddTrack(track_);
727 }
Steve Anton3871f6f2018-01-26 18:25:53728 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:13729 }
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 18:25:53735 void AddOutgoingAudioTrack(FakePeerConnectionForStats* pc,
736 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 14:26:13737 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kLocalTrackId);
738 if (GetParam()) {
739 if (!stream_)
Seth Hampson845e8782018-03-02 19:34:10740 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 14:26:13741 stream_->AddTrack(audio_track_);
742 stats->AddStream(stream_);
743 } else {
744 stats->AddTrack(audio_track_);
745 }
Steve Anton3871f6f2018-01-26 18:25:53746 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:13747 }
748
749 // Adds a incoming audio track with a given SSRC into the stats.
Steve Anton3871f6f2018-01-26 18:25:53750 void AddIncomingAudioTrack(FakePeerConnectionForStats* pc,
751 StatsCollectorForTest* stats) {
Harald Alvestrand75ceef22018-01-04 14:26:13752 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId);
753 if (GetParam()) {
754 if (stream_ == NULL)
Seth Hampson845e8782018-03-02 19:34:10755 stream_ = MediaStream::Create("streamid");
Harald Alvestrand75ceef22018-01-04 14:26:13756 stream_->AddTrack(audio_track_);
757 stats->AddStream(stream_);
758 } else {
759 stats->AddTrack(audio_track_);
760 }
Steve Anton3871f6f2018-01-26 18:25:53761 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:13762 }
763
Steve Anton3871f6f2018-01-26 18:25:53764 rtc::scoped_refptr<MediaStream> stream_;
765 rtc::scoped_refptr<VideoTrack> track_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52766 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36767};
768
zhihuang6ba3b192016-05-13 18:46:35769TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
Steve Anton3871f6f2018-01-26 18:25:53770 auto pc = CreatePeerConnection();
771 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 18:46:35772
Steve Anton3871f6f2018-01-26 18:25:53773 pc->AddSctpDataChannel("hacks");
zhihuang6ba3b192016-05-13 18:46:35774
Steve Anton3871f6f2018-01-26 18:25:53775 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 18:46:35776 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:53777 stats->GetStats(nullptr, &reports);
zhihuang6ba3b192016-05-13 18:46:35778
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:07787// Verify that ExtractDataInfo populates reports.
788TEST_F(StatsCollectorTest, ExtractDataInfo) {
Steve Anton3871f6f2018-01-26 18:25:53789 const std::string kDataChannelLabel = "hacks";
790 constexpr int kDataChannelId = 31337;
791 const std::string kConnectingString = DataChannelInterface::DataStateString(
decurtis@webrtc.org487a4442015-01-15 22:55:07792 DataChannelInterface::DataState::kConnecting);
793
Steve Anton3871f6f2018-01-26 18:25:53794 auto pc = CreatePeerConnection();
795 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07796
Steve Anton3871f6f2018-01-26 18:25:53797 InternalDataChannelInit init;
798 init.id = kDataChannelId;
799 pc->AddSctpDataChannel(kDataChannelLabel, init);
decurtis@webrtc.org487a4442015-01-15 22:55:07800
Steve Anton3871f6f2018-01-26 18:25:53801 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
decurtis@webrtc.org487a4442015-01-15 22:55:07802 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:53803 stats->GetStats(nullptr, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37804
805 const StatsReport* report =
806 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
807
Steve Anton3871f6f2018-01-26 18:25:53808 StatsReport::Id report_id = StatsReport::NewTypedIntId(
809 StatsReport::kStatsReportTypeDataChannel, kDataChannelId);
decurtis@webrtc.org322a5642015-02-03 22:09:37810
Steve Anton3871f6f2018-01-26 18:25:53811 EXPECT_TRUE(report_id->Equals(report->id()));
decurtis@webrtc.org322a5642015-02-03 22:09:37812
Steve Anton3871f6f2018-01-26 18:25:53813 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
814 EXPECT_EQ(kDataChannelLabel,
815 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
816 StatsReport::kStatsValueNameLabel));
Jonas Olsson6b1985d2018-07-05 09:59:48817 EXPECT_EQ(rtc::ToString(kDataChannelId),
Peter Boström0c4e06b2015-10-07 10:23:21818 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07819 StatsReport::kStatsValueNameDataChannelId));
Steve Anton3871f6f2018-01-26 18:25:53820 EXPECT_EQ(kConnectingString,
821 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
822 StatsReport::kStatsValueNameState));
Yves Gerey665174f2018-06-19 13:03:05823 EXPECT_EQ("",
824 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
825 StatsReport::kStatsValueNameProtocol));
decurtis@webrtc.org487a4442015-01-15 22:55:07826}
827
henrike@webrtc.org28e20752013-07-10 00:45:36828// This test verifies that 64-bit counters are passed successfully.
Harald Alvestrand75ceef22018-01-04 14:26:13829TEST_P(StatsCollectorTrackTest, BytesCounterHandles64Bits) {
henrike@webrtc.org28e20752013-07-10 00:45:36830 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Steve Anton3871f6f2018-01-26 18:25:53831 constexpr int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36832
Steve Anton3871f6f2018-01-26 18:25:53833 auto pc = CreatePeerConnection();
834 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36835
Steve Anton3871f6f2018-01-26 18:25:53836 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06837 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36838 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 18:25:53839 VideoMediaInfo video_info;
840 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:20841
842 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
843 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36844
Steve Anton3871f6f2018-01-26 18:25:53845 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:36854}
855
Alex Narest42308f62017-06-19 15:58:12856// Test that audio BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 14:26:13857TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) {
Alex Narest42308f62017-06-19 15:58:12858 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
859 // BWE.
Steve Anton3871f6f2018-01-26 18:25:53860 constexpr int64_t kBytesSent = 12345678901234LL;
861 constexpr int kSendBandwidth = 1234567;
862 constexpr int kRecvBandwidth = 12345678;
863 constexpr int kPacerDelay = 123;
Alex Narest42308f62017-06-19 15:58:12864
Steve Anton3871f6f2018-01-26 18:25:53865 auto pc = CreatePeerConnection();
866 auto stats = CreateStatsCollector(pc);
Alex Narest42308f62017-06-19 15:58:12867
Steve Anton3871f6f2018-01-26 18:25:53868 VoiceSenderInfo voice_sender_info;
Alex Narest42308f62017-06-19 15:58:12869 voice_sender_info.add_ssrc(1234);
870 voice_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 18:25:53871 VoiceMediaInfo voice_info;
872 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-03 00:00:20873
874 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
875 voice_media_channel->SetStats(voice_info);
Alex Narest42308f62017-06-19 15:58:12876
Steve Anton3871f6f2018-01-26 18:25:53877 AddOutgoingAudioTrack(pc, stats.get());
878
879 Call::Stats call_stats;
Alex Narest42308f62017-06-19 15:58:12880 call_stats.send_bandwidth_bps = kSendBandwidth;
881 call_stats.recv_bandwidth_bps = kRecvBandwidth;
882 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 18:25:53883 pc->SetCallStats(call_stats);
Alex Narest42308f62017-06-19 15:58:12884
Steve Anton3871f6f2018-01-26 18:25:53885 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 15:58:12902}
903
904// Test that video BWE information is reported via stats.
Harald Alvestrand75ceef22018-01-04 14:26:13905TEST_P(StatsCollectorTrackTest, VideoBandwidthEstimationInfoIsReported) {
henrike@webrtc.org28e20752013-07-10 00:45:36906 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
907 // BWE.
Steve Anton3871f6f2018-01-26 18:25:53908 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:36912
Steve Anton3871f6f2018-01-26 18:25:53913 auto pc = CreatePeerConnection();
914 auto stats = CreateStatsCollector(pc);
henrike@webrtc.org28e20752013-07-10 00:45:36915
Steve Anton3871f6f2018-01-26 18:25:53916 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06917 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36918 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 18:25:53919 VideoMediaInfo video_info;
920 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:20921
922 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
923 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:36924
Steve Anton3871f6f2018-01-26 18:25:53925 AddOutgoingVideoTrack(pc, stats.get());
926
927 Call::Stats call_stats;
stefanf79ade12017-06-02 13:44:03928 call_stats.send_bandwidth_bps = kSendBandwidth;
929 call_stats.recv_bandwidth_bps = kRecvBandwidth;
930 call_stats.pacer_delay_ms = kPacerDelay;
Steve Anton3871f6f2018-01-26 18:25:53931 pc->SetCallStats(call_stats);
wu@webrtc.org97077a32013-10-25 21:18:33932
Steve Anton3871f6f2018-01-26 18:25:53933 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:36950}
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 18:25:53955 auto pc = CreatePeerConnection();
956 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07957
Steve Anton3871f6f2018-01-26 18:25:53958 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:36964}
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 18:25:53969 auto pc = CreatePeerConnection();
970 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07971
Steve Anton3871f6f2018-01-26 18:25:53972 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:36981}
982
983// This test verifies that the empty track report exists in the returned stats
984// without calling StatsCollector::UpdateStats.
Harald Alvestrand75ceef22018-01-04 14:26:13985TEST_P(StatsCollectorTrackTest, TrackObjectExistsWithoutUpdateStats) {
Steve Anton3871f6f2018-01-26 18:25:53986 auto pc = CreatePeerConnection();
987 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:07988
Steve Anton5b387312018-02-03 00:00:20989 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 18:25:53990 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:36991
henrike@webrtc.org28e20752013-07-10 00:45:36992 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26993 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:53994 stats->GetStats(nullptr, &reports);
995 ASSERT_EQ(1u, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18996 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 22:06:43997 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36998
999 std::string trackValue =
Yves Gerey665174f2018-06-19 13:03:051000 ExtractStatsValue(StatsReport::kStatsReportTypeTrack, reports,
henrike@webrtc.org40b3b682014-03-03 18:30:111001 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051002 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:361003}
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 14:26:131007TEST_P(StatsCollectorTrackTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
Steve Anton3871f6f2018-01-26 18:25:531008 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:071009
Steve Anton3871f6f2018-01-26 18:25:531010 auto pc = CreatePeerConnection();
1011 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 18:50:271012
Steve Anton3871f6f2018-01-26 18:25:531013 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:061014 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:361015 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 18:25:531016 VideoMediaInfo video_info;
1017 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:201018
1019 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1020 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:361021
Steve Anton3871f6f2018-01-26 18:25:531022 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:361023
Steve Anton3871f6f2018-01-26 18:25:531024 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:261025 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:531026 stats->GetStats(nullptr, &reports);
1027
wu@webrtc.org97077a32013-10-25 21:18:331028 // |reports| should contain at least one session report, one track report,
1029 // and one ssrc report.
Steve Anton3871f6f2018-01-26 18:25:531030 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 13:03:051031 const StatsReport* track_report =
1032 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:051033 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:361034
xians@webrtc.org4cb01282014-06-12 14:57:051035 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:301036 reports.clear();
Steve Anton3871f6f2018-01-26 18:25:531037 stats->GetStats(track_, &reports);
wu@webrtc.org97077a32013-10-25 21:18:331038 // |reports| should contain at least one session report, one track report,
1039 // and one ssrc report.
Steve Anton3871f6f2018-01-26 18:25:531040 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 13:03:051041 track_report =
1042 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131043 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 18:25:531044 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:361045
Yves Gerey665174f2018-06-19 13:03:051046 std::string ssrc_id =
1047 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 09:59:481048 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:361049
Yves Gerey665174f2018-06-19 13:03:051050 std::string track_id =
1051 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051052 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 09:27:151053
Yves Gerey665174f2018-06-19 13:03:051054 std::string media_type =
1055 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameMediaType);
fippobec70ab2016-01-28 09:27:151056 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:361057}
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 14:26:131061TEST_P(StatsCollectorTrackTest, TransportObjectLinkedFromSsrcObject) {
Steve Anton3871f6f2018-01-26 18:25:531062 constexpr int64_t kBytesSent = 12345678901234LL;
decurtis@webrtc.org487a4442015-01-15 22:55:071063
Steve Anton3871f6f2018-01-26 18:25:531064 auto pc = CreatePeerConnection();
1065 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 18:50:271066
Steve Anton3871f6f2018-01-26 18:25:531067 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:061068 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:361069 video_sender_info.bytes_sent = kBytesSent;
Steve Anton3871f6f2018-01-26 18:25:531070 VideoMediaInfo video_info;
1071 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:201072
1073 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1074 video_media_channel->SetStats(video_info);
henrike@webrtc.org28e20752013-07-10 00:45:361075
Steve Anton3871f6f2018-01-26 18:25:531076 AddOutgoingVideoTrack(pc, stats.get());
henrike@webrtc.org28e20752013-07-10 00:45:361077
Steve Anton3871f6f2018-01-26 18:25:531078 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:261079 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:531080 stats->GetStats(nullptr, &reports);
1081
Yves Gerey665174f2018-06-19 13:03:051082 std::string transport_id =
1083 ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports,
1084 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:361085 ASSERT_NE(kNotFound, transport_id);
Steve Anton3871f6f2018-01-26 18:25:531086
tommi@webrtc.org4fb7e252015-01-21 11:36:181087 // 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:551097 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:181098 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:551099 const StatsReport* transport_report = FindReportById(reports, id);
Steve Anton3871f6f2018-01-26 18:25:531100 ASSERT_TRUE(transport_report);
henrike@webrtc.org28e20752013-07-10 00:45:361101}
1102
wu@webrtc.org97077a32013-10-25 21:18:331103// 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 14:26:131105TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsAbsent) {
Steve Anton3871f6f2018-01-26 18:25:531106 auto pc = CreatePeerConnection();
1107 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071108
Steve Anton5b387312018-02-03 00:00:201109 pc->AddVideoChannel("video", "transport");
Steve Anton3871f6f2018-01-26 18:25:531110 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:331111
Steve Anton3871f6f2018-01-26 18:25:531112 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:111113 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:531114 stats->GetStats(nullptr, &reports);
1115
Yves Gerey665174f2018-06-19 13:03:051116 const StatsReport* remote_report =
1117 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 18:25:531118 EXPECT_FALSE(remote_report);
wu@webrtc.org97077a32013-10-25 21:18:331119}
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 14:26:131123TEST_P(StatsCollectorTrackTest, RemoteSsrcInfoIsPresent) {
Steve Anton3871f6f2018-01-26 18:25:531124 auto pc = CreatePeerConnection();
1125 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071126
Steve Anton3871f6f2018-01-26 18:25:531127 SsrcReceiverInfo remote_ssrc_stats;
wu@webrtc.org97077a32013-10-25 21:18:331128 remote_ssrc_stats.timestamp = 12345.678;
1129 remote_ssrc_stats.ssrc = kSsrcOfTrack;
Steve Anton3871f6f2018-01-26 18:25:531130 VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:061131 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:331132 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
Steve Anton3871f6f2018-01-26 18:25:531133 VideoMediaInfo video_info;
1134 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:201135
1136 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1137 video_media_channel->SetStats(video_info);
wu@webrtc.org97077a32013-10-25 21:18:331138
Steve Anton3871f6f2018-01-26 18:25:531139 AddOutgoingVideoTrack(pc, stats.get());
wu@webrtc.org97077a32013-10-25 21:18:331140
Steve Anton3871f6f2018-01-26 18:25:531141 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:261142 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:531143 stats->GetStats(nullptr, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:051144
Yves Gerey665174f2018-06-19 13:03:051145 const StatsReport* remote_report =
1146 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
Steve Anton3871f6f2018-01-26 18:25:531147 ASSERT_TRUE(remote_report);
decurtis@webrtc.org322a5642015-02-03 22:09:371148 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:331149}
1150
xians@webrtc.org4cb01282014-06-12 14:57:051151// 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 14:26:131153TEST_P(StatsCollectorTrackTest, ReportsFromRemoteTrack) {
Steve Anton3871f6f2018-01-26 18:25:531154 constexpr int64_t kNumOfPacketsConcealed = 54321;
decurtis@webrtc.org487a4442015-01-15 22:55:071155
Steve Anton3871f6f2018-01-26 18:25:531156 auto pc = CreatePeerConnection();
1157 auto stats = CreateStatsCollector(pc);
deadbeefcbecd352015-09-23 18:50:271158
Steve Anton3871f6f2018-01-26 18:25:531159 VideoReceiverInfo video_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:051160 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:031161 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
Steve Anton3871f6f2018-01-26 18:25:531162 VideoMediaInfo video_info;
1163 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-03 00:00:201164
1165 auto* video_media_info = pc->AddVideoChannel("video", "transport");
1166 video_media_info->SetStats(video_info);
xians@webrtc.org4cb01282014-06-12 14:57:051167
Steve Anton3871f6f2018-01-26 18:25:531168 AddIncomingVideoTrack(pc, stats.get());
xians@webrtc.org4cb01282014-06-12 14:57:051169
Steve Anton3871f6f2018-01-26 18:25:531170 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:261171 StatsReports reports;
Steve Anton3871f6f2018-01-26 18:25:531172 stats->GetStats(nullptr, &reports);
1173
xians@webrtc.org4cb01282014-06-12 14:57:051174 // |reports| should contain at least one session report, one track report,
1175 // and one ssrc report.
Steve Anton3871f6f2018-01-26 18:25:531176 EXPECT_LE(3u, reports.size());
Yves Gerey665174f2018-06-19 13:03:051177 const StatsReport* track_report =
1178 FindNthReportByType(reports, StatsReport::kStatsReportTypeTrack, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131179 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 18:25:531180 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:051181
Yves Gerey665174f2018-06-19 13:03:051182 std::string ssrc_id =
1183 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 09:59:481184 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:051185
Yves Gerey665174f2018-06-19 13:03:051186 std::string track_id =
1187 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051188 EXPECT_EQ(kRemoteTrackId, track_id);
1189}
1190
guoweis@webrtc.org950c5182014-12-16 23:01:311191// 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 18:25:531194 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:071197
Steve Anton3871f6f2018-01-26 18:25:531198 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:311201
Steve Anton3871f6f2018-01-26 18:25:531202 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:311205
Steve Anton3871f6f2018-01-26 18:25:531206 auto pc = CreatePeerConnection();
1207 auto stats = CreateStatsCollector(pc);
guoweis@webrtc.org950c5182014-12-16 23:01:311208
Steve Anton3871f6f2018-01-26 18:25:531209 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:311216
Steve Anton3871f6f2018-01-26 18:25:531217 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:311224
Steve Anton3871f6f2018-01-26 18:25:531225 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-03 00:00:201231 pc->AddVoiceChannel("audio", kTransportName);
Steve Anton3871f6f2018-01-26 18:25:531232 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:311237
1238 // Verify the local candidate report is populated correctly.
1239 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 18:25:531240 "Cand-" + local.id(),
1241 ExtractStatsValue(StatsReport::kStatsReportTypeCandidatePair, reports,
1242 StatsReport::kStatsValueNameLocalCandidateId));
1243 EXPECT_EQ(
1244 kLocalIp,
guoweis@webrtc.org950c5182014-12-16 23:01:311245 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1246 StatsReport::kStatsValueNameCandidateIPAddress));
1247 EXPECT_EQ(
Steve Anton3871f6f2018-01-26 18:25:531248 rtc::ToString(kLocalPort),
guoweis@webrtc.org950c5182014-12-16 23:01:311249 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 18:25:531256 rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:311257 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 18:25:531264 AdapterTypeToStatsType(kNetworkType),
guoweis@webrtc.org950c5182014-12-16 23:01:311265 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1266 StatsReport::kStatsValueNameCandidateNetworkType));
1267
1268 // Verify the remote candidate report is populated correctly.
Steve Anton3871f6f2018-01-26 18:25:531269 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:311274 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1275 reports,
1276 StatsReport::kStatsValueNameCandidateIPAddress));
Steve Anton3871f6f2018-01-26 18:25:531277 EXPECT_EQ(rtc::ToString(kRemotePort),
guoweis@webrtc.org950c5182014-12-16 23:01:311278 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 18:25:531285 EXPECT_EQ(rtc::ToString(kPriority),
guoweis@webrtc.org950c5182014-12-16 23:01:311286 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:361299// This test verifies that all chained certificates are correctly
1300// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:271301TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:361302 // 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 21:04:511309 rtc::FakeSSLIdentity local_identity(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:361310
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 21:04:511317 rtc::FakeSSLIdentity remote_identity(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:361318
Taylor Brandstetterc3928662018-02-23 21:04:511319 TestCertificateReports(local_identity, local_ders, remote_identity,
kwibergb4d01c42016-04-06 12:15:061320 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:361321}
1322
1323// This test verifies that all certificates without chains are correctly
1324// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:271325TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:361326 // Build local certificate.
1327 std::string local_der = "This is the local der.";
Taylor Brandstetterc3928662018-02-23 21:04:511328 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:361329
1330 // Build remote certificate.
1331 std::string remote_der = "This is somebody else's der.";
Taylor Brandstetterc3928662018-02-23 21:04:511332 rtc::FakeSSLIdentity remote_identity(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:361333
Taylor Brandstetterc3928662018-02-23 21:04:511334 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1335 remote_identity,
kwibergb4d01c42016-04-06 12:15:061336 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:361337}
1338
1339// This test verifies that the stats are generated correctly when no
1340// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:271341TEST_F(StatsCollectorTest, NoTransport) {
Steve Anton3871f6f2018-01-26 18:25:531342 auto pc = CreatePeerConnection();
1343 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071344
Steve Anton3871f6f2018-01-26 18:25:531345 // This will cause the fake PeerConnection to generate a TransportStats entry
1346 // but with only a single dummy TransportChannelStats.
Steve Anton5b387312018-02-03 00:00:201347 pc->AddVoiceChannel("audio", "transport");
deadbeefcbecd352015-09-23 18:50:271348
Steve Anton3871f6f2018-01-26 18:25:531349 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1350 StatsReports reports;
1351 stats->GetStats(nullptr, &reports);
wu@webrtc.org4551b792013-10-09 15:37:361352
1353 // Check that the local certificate is absent.
Yves Gerey665174f2018-06-19 13:03:051354 std::string local_certificate_id =
1355 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1356 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:361357 ASSERT_EQ(kNotFound, local_certificate_id);
1358
1359 // Check that the remote certificate is absent.
Yves Gerey665174f2018-06-19 13:03:051360 std::string remote_certificate_id =
1361 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1362 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:361363 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:301364
1365 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-19 03:41:531366 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:361374}
1375
wu@webrtc.orgb9a088b2014-02-13 23:18:491376// 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 21:04:511381 rtc::FakeSSLIdentity local_identity(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:491382
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 21:04:511385 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:491388
Taylor Brandstetterc3928662018-02-23 21:04:511389 TestCertificateReports(local_identity, std::vector<std::string>(1, local_der),
1390 remote_identity, std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:491391}
1392
zhihuang6ba3b192016-05-13 18:46:351393// This test verifies that the audio/video related stats which are -1 initially
1394// will be filtered out.
Harald Alvestrand75ceef22018-01-04 14:26:131395TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) {
Harald Alvestrand75ceef22018-01-04 14:26:131396 // This test uses streams, but only works for the stream case.
Steve Anton3871f6f2018-01-26 18:25:531397 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 14:26:131398 return;
Steve Anton3871f6f2018-01-26 18:25:531399 }
zhihuang6ba3b192016-05-13 18:46:351400
Steve Anton3871f6f2018-01-26 18:25:531401 auto pc = CreatePeerConnection();
1402 auto stats = CreateStatsCollector(pc);
zhihuang6ba3b192016-05-13 18:46:351403
1404 // Create a local stream with a local audio track and adds it to the stats.
Seth Hampson845e8782018-03-02 19:34:101405 stream_ = MediaStream::Create("streamid");
zhihuang6ba3b192016-05-13 18:46:351406 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1407 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1408 stream_->AddTrack(local_track);
Steve Anton3871f6f2018-01-26 18:25:531409 pc->AddLocalTrack(kSsrcOfTrack, kLocalTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:131410 if (GetParam()) {
Steve Anton3871f6f2018-01-26 18:25:531411 stats->AddStream(stream_);
Harald Alvestrand75ceef22018-01-04 14:26:131412 }
Steve Anton3871f6f2018-01-26 18:25:531413 stats->AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
zhihuang6ba3b192016-05-13 18:46:351414
1415 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 18:25:531416 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 19:34:101417 MediaStream::Create("remotestreamid"));
zhihuang6ba3b192016-05-13 18:46:351418 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1419 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
zhihuang6ba3b192016-05-13 18:46:351420 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 18:25:531421 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
Harald Alvestrand75ceef22018-01-04 14:26:131422 if (GetParam()) {
Steve Anton3871f6f2018-01-26 18:25:531423 stats->AddStream(remote_stream);
Harald Alvestrand75ceef22018-01-04 14:26:131424 }
zhihuang6ba3b192016-05-13 18:46:351425
Steve Anton3871f6f2018-01-26 18:25:531426 VoiceSenderInfo voice_sender_info;
zhihuang6ba3b192016-05-13 18:46:351427 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 Creusen56d460902017-11-24 16:29:591436 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info,
1437 true);
zhihuang6ba3b192016-05-13 18:46:351438
Steve Anton3871f6f2018-01-26 18:25:531439 VoiceReceiverInfo voice_receiver_info;
zhihuang6ba3b192016-05-13 18:46:351440 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 18:25:531445 VoiceMediaInfo voice_info;
1446 voice_info.senders.push_back(voice_sender_info);
1447 voice_info.receivers.push_back(voice_receiver_info);
zhihuang6ba3b192016-05-13 18:46:351448
Steve Anton5b387312018-02-03 00:00:201449 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1450 voice_media_channel->SetStats(voice_info);
zhihuang6ba3b192016-05-13 18:46:351451
Steve Anton3871f6f2018-01-26 18:25:531452 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
zhihuang6ba3b192016-05-13 18:46:351453
1454 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 18:25:531455 StatsReports reports;
1456 stats->GetStats(local_track.get(), &reports);
zhihuang6ba3b192016-05-13 18:46:351457 const StatsReport* report =
1458 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131459 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 18:46:351460 // 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 18:46:351468 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 18:25:531475 stats->GetStats(remote_track.get(), &reports);
zhihuang6ba3b192016-05-13 18:46:351476 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131477 ASSERT_TRUE(report);
zhihuang6ba3b192016-05-13 18:46:351478 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:111485// This test verifies that a local stats object can get statistics via
1486// AudioTrackInterface::GetStats() method.
Harald Alvestrand75ceef22018-01-04 14:26:131487TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) {
Steve Anton3871f6f2018-01-26 18:25:531488 auto pc = CreatePeerConnection();
1489 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071490
Steve Anton3871f6f2018-01-26 18:25:531491 AddOutgoingAudioTrack(pc, stats.get());
1492 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
tommi@webrtc.org242068d2014-07-14 20:19:561493
Steve Anton3871f6f2018-01-26 18:25:531494 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:051495 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 18:25:531496 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
1497 VoiceMediaInfo voice_info;
1498 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-03 00:00:201499
1500 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1501 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:111502
henrike@webrtc.org40b3b682014-03-03 18:30:111503 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 18:25:531504 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:111505
xians@webrtc.org4cb01282014-06-12 14:57:051506 // Verify that there is no remote report for the local audio track because
1507 // we did not set it up.
Yves Gerey665174f2018-06-19 13:03:051508 const StatsReport* remote_report =
1509 FindNthReportByType(reports, StatsReport::kStatsReportTypeRemoteSsrc, 1);
xians@webrtc.org4cb01282014-06-12 14:57:051510 EXPECT_TRUE(remote_report == NULL);
1511}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:101512
1513// This test verifies that audio receive streams populate stats reports
1514// correctly.
Harald Alvestrand75ceef22018-01-04 14:26:131515TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) {
Steve Anton3871f6f2018-01-26 18:25:531516 auto pc = CreatePeerConnection();
1517 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071518
Steve Anton3871f6f2018-01-26 18:25:531519 AddIncomingAudioTrack(pc, stats.get());
deadbeefcbecd352015-09-23 18:50:271520
Steve Anton3871f6f2018-01-26 18:25:531521 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:051522 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:011523 voice_receiver_info.codec_name = "fake_codec";
Steve Anton3871f6f2018-01-26 18:25:531524 VoiceMediaInfo voice_info;
1525 voice_info.receivers.push_back(voice_receiver_info);
Steve Anton5b387312018-02-03 00:00:201526
1527 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1528 voice_media_channel->SetStats(voice_info);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:101529
buildbot@webrtc.org3e01e0b2014-05-13 17:54:101530 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 18:25:531531 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:101532}
1533
henrike@webrtc.org40b3b682014-03-03 18:30:111534// This test verifies that a local stats object won't update its statistics
1535// after a RemoveLocalAudioTrack() call.
Harald Alvestrand75ceef22018-01-04 14:26:131536TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) {
Steve Anton3871f6f2018-01-26 18:25:531537 auto pc = CreatePeerConnection();
1538 auto stats = CreateStatsCollector(pc);
decurtis@webrtc.org487a4442015-01-15 22:55:071539
Steve Anton3871f6f2018-01-26 18:25:531540 AddOutgoingAudioTrack(pc, stats.get());
1541 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
deadbeefcbecd352015-09-23 18:50:271542
Steve Anton3871f6f2018-01-26 18:25:531543 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:051544 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 18:25:531545 VoiceMediaInfo voice_info;
1546 voice_info.senders.push_back(voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:111547
Steve Anton5b387312018-02-03 00:00:201548 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1549 voice_media_channel->SetStats(voice_info);
henrike@webrtc.org40b3b682014-03-03 18:30:111550
Steve Anton3871f6f2018-01-26 18:25:531551 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:111552
Steve Anton3871f6f2018-01-26 18:25:531553 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1554 StatsReports reports;
1555 stats->GetStats(nullptr, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:111556
1557 // The report will exist since we don't remove them in RemoveStream().
Yves Gerey665174f2018-06-19 13:03:051558 const StatsReport* report =
1559 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Steve Anton3871f6f2018-01-26 18:25:531560 ASSERT_TRUE(report);
1561 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
Yves Gerey665174f2018-06-19 13:03:051562 std::string track_id =
1563 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051564 EXPECT_EQ(kLocalTrackId, track_id);
Yves Gerey665174f2018-06-19 13:03:051565 std::string ssrc_id =
1566 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameSsrc);
Jonas Olsson6b1985d2018-07-05 09:59:481567 EXPECT_EQ(rtc::ToString(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:111568
1569 // Verifies the values in the track report, no value will be changed by the
1570 // AudioTrackInterface::GetSignalValue() and
Sam Zackrisson28127632018-11-01 10:37:151571 // AudioProcessorInterface::GetStats();
henrike@webrtc.org40b3b682014-03-03 18:30:111572 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1573}
1574
xians@webrtc.org4cb01282014-06-12 14:57:051575// 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 14:26:131577TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) {
Steve Anton3871f6f2018-01-26 18:25:531578 auto pc = CreatePeerConnection();
1579 auto stats = CreateStatsCollector(pc);
xians@webrtc.org4cb01282014-06-12 14:57:051580
1581 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 18:25:531582 AddOutgoingAudioTrack(pc, stats.get());
1583 stats->AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org4cb01282014-06-12 14:57:051584
1585 // Create a remote stream with a remote audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 18:25:531586 rtc::scoped_refptr<MediaStream> remote_stream(
Seth Hampson845e8782018-03-02 19:34:101587 MediaStream::Create("remotestreamid"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:521588 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1589 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
Steve Anton3871f6f2018-01-26 18:25:531590 pc->AddRemoteTrack(kSsrcOfTrack, kRemoteTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051591 remote_stream->AddTrack(remote_track);
Steve Anton3871f6f2018-01-26 18:25:531592 stats->AddStream(remote_stream);
xians@webrtc.org4cb01282014-06-12 14:57:051593
Steve Anton3871f6f2018-01-26 18:25:531594 VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:051595 InitVoiceSenderInfo(&voice_sender_info);
xians@webrtc.org4cb01282014-06-12 14:57:051596 // Some of the contents in |voice_sender_info| needs to be updated from the
1597 // |audio_track_|.
Ivo Creusen56d460902017-11-24 16:29:591598 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info,
1599 true);
xians@webrtc.org4cb01282014-06-12 14:57:051600
Steve Anton3871f6f2018-01-26 18:25:531601 VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:051602 InitVoiceReceiverInfo(&voice_receiver_info);
1603
1604 // Constructs an ssrc stats update.
Steve Anton3871f6f2018-01-26 18:25:531605 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:051608
Steve Anton3871f6f2018-01-26 18:25:531609 // Instruct the session to return stats containing the transport channel.
Steve Anton5b387312018-02-03 00:00:201610 auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport");
1611 voice_media_channel->SetStats(voice_info);
xians@webrtc.org4cb01282014-06-12 14:57:051612
Steve Anton3871f6f2018-01-26 18:25:531613 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
xians@webrtc.org4cb01282014-06-12 14:57:051614
1615 // Get stats for the local track.
Steve Anton3871f6f2018-01-26 18:25:531616 StatsReports reports; // returned values.
1617 stats->GetStats(audio_track_.get(), &reports);
1618
Yves Gerey665174f2018-06-19 13:03:051619 const StatsReport* track_report =
1620 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131621 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 18:25:531622 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 13:03:051623 std::string track_id =
1624 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051625 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:301629 reports.clear();
Steve Anton3871f6f2018-01-26 18:25:531630 stats->GetStats(remote_track.get(), &reports);
Yves Gerey665174f2018-06-19 13:03:051631 track_report =
1632 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
Harald Alvestrand75ceef22018-01-04 14:26:131633 ASSERT_TRUE(track_report);
Steve Anton3871f6f2018-01-26 18:25:531634 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
Yves Gerey665174f2018-06-19 13:03:051635 track_id =
1636 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:051637 EXPECT_EQ(kRemoteTrackId, track_id);
1638 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1639}
1640
xians@webrtc.org01bda202014-07-09 07:38:381641// 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 14:26:131645TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) {
Harald Alvestrand75ceef22018-01-04 14:26:131646 // This test only makes sense when we're using streams.
Steve Anton3871f6f2018-01-26 18:25:531647 if (!GetParam()) {
Harald Alvestrand75ceef22018-01-04 14:26:131648 return;
Steve Anton3871f6f2018-01-26 18:25:531649 }
Harald Alvestrand75ceef22018-01-04 14:26:131650
Steve Anton3871f6f2018-01-26 18:25:531651 auto pc = CreatePeerConnection();
1652 auto stats = CreateStatsCollector(pc);
xians@webrtc.org01bda202014-07-09 07:38:381653
1654 // Create a local stream with a local audio track and adds it to the stats.
Steve Anton3871f6f2018-01-26 18:25:531655 AddOutgoingAudioTrack(pc, stats.get());
1656 stats->AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:381657
Steve Anton3871f6f2018-01-26 18:25:531658 VoiceSenderInfo voice_sender_info;
ivoce1198e02017-09-08 15:13:191659 InitVoiceSenderInfo(&voice_sender_info);
Steve Anton3871f6f2018-01-26 18:25:531660 UpdateVoiceSenderInfoFromAudioTrack(audio_track_, &voice_sender_info, false);
xians@webrtc.org01bda202014-07-09 07:38:381661 voice_sender_info.add_ssrc(kSsrcOfTrack);
Steve Anton3871f6f2018-01-26 18:25:531662 VoiceMediaInfo voice_info;
1663 voice_info.senders.push_back(voice_sender_info);
Steve Anton5b387312018-02-03 00:00:201664
1665 auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport");
1666 voice_media_channel->SetStats(voice_info);
xians@webrtc.org01bda202014-07-09 07:38:381667
xians@webrtc.org01bda202014-07-09 07:38:381668 StatsReports reports; // returned values.
Steve Anton3871f6f2018-01-26 18:25:531669 VerifyAudioTrackStats(audio_track_, stats.get(), voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:381670
1671 // Remove the previous audio track from the stream.
1672 stream_->RemoveTrack(audio_track_.get());
Steve Anton3871f6f2018-01-26 18:25:531673 stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
xians@webrtc.org01bda202014-07-09 07:38:381674
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:521677 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1678 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
Steve Anton3871f6f2018-01-26 18:25:531679 pc->AddLocalTrack(kSsrcOfTrack, kNewTrackId);
xians@webrtc.org01bda202014-07-09 07:38:381680 stream_->AddTrack(new_audio_track);
1681
Steve Anton3871f6f2018-01-26 18:25:531682 stats->AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
1683 stats->ClearUpdateStatsCacheForTest();
1684
1685 VoiceSenderInfo new_voice_sender_info;
xians@webrtc.org01bda202014-07-09 07:38:381686 InitVoiceSenderInfo(&new_voice_sender_info);
Steve Anton3871f6f2018-01-26 18:25:531687 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-03 00:00:201691 voice_media_channel->SetStats(new_voice_info);
Steve Anton3871f6f2018-01-26 18:25:531692
tommi@webrtc.org5b06b062014-08-15 08:38:301693 reports.clear();
Steve Anton3871f6f2018-01-26 18:25:531694 VerifyAudioTrackStats(new_audio_track, stats.get(), new_voice_info, &reports);
xians@webrtc.org01bda202014-07-09 07:38:381695}
1696
sakal43536c32016-10-24 08:46:431697// This test verifies that stats are correctly set in video send ssrc stats.
Harald Alvestrand75ceef22018-01-04 14:26:131698TEST_P(StatsCollectorTrackTest, VerifyVideoSendSsrcStats) {
Steve Anton3871f6f2018-01-26 18:25:531699 auto pc = CreatePeerConnection();
1700 auto stats = CreateStatsCollector(pc);
sakal43536c32016-10-24 08:46:431701
Steve Anton3871f6f2018-01-26 18:25:531702 AddOutgoingVideoTrack(pc, stats.get());
sakal43536c32016-10-24 08:46:431703
Steve Anton3871f6f2018-01-26 18:25:531704 VideoSenderInfo video_sender_info;
sakal43536c32016-10-24 08:46:431705 video_sender_info.add_ssrc(1234);
1706 video_sender_info.frames_encoded = 10;
Oskar Sundbom36f8f3e2017-11-16 09:54:271707 video_sender_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 18:25:531708 VideoMediaInfo video_info;
1709 video_info.senders.push_back(video_sender_info);
Steve Anton5b387312018-02-03 00:00:201710
1711 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1712 video_media_channel->SetStats(video_info);
sakal43536c32016-10-24 08:46:431713
Steve Anton3871f6f2018-01-26 18:25:531714 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1715 StatsReports reports;
1716 stats->GetStats(nullptr, &reports);
1717
sakal43536c32016-10-24 08:46:431718 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
1719 ExtractSsrcStatsValue(reports,
1720 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 13:53:471721 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
1722 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 08:46:431723}
1724
sakale5ba44e2016-10-26 14:09:241725// This test verifies that stats are correctly set in video receive ssrc stats.
Steve Anton3871f6f2018-01-26 18:25:531726TEST_P(StatsCollectorTrackTest, VerifyVideoReceiveSsrcStatsNew) {
1727 auto pc = CreatePeerConnection();
1728 auto stats = CreateStatsCollector(pc);
sakale5ba44e2016-10-26 14:09:241729
Steve Anton3871f6f2018-01-26 18:25:531730 AddIncomingVideoTrack(pc, stats.get());
sakale5ba44e2016-10-26 14:09:241731
Steve Anton3871f6f2018-01-26 18:25:531732 VideoReceiverInfo video_receiver_info;
sakale5ba44e2016-10-26 14:09:241733 video_receiver_info.add_ssrc(1234);
1734 video_receiver_info.frames_decoded = 10;
Artem Titov8a3ab0e2018-07-27 14:52:571735 video_receiver_info.qp_sum = 11;
Steve Anton3871f6f2018-01-26 18:25:531736 VideoMediaInfo video_info;
1737 video_info.receivers.push_back(video_receiver_info);
Steve Anton5b387312018-02-03 00:00:201738
1739 auto* video_media_channel = pc->AddVideoChannel("video", "transport");
1740 video_media_channel->SetStats(video_info);
sakale5ba44e2016-10-26 14:09:241741
Steve Anton3871f6f2018-01-26 18:25:531742 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1743 StatsReports reports;
1744 stats->GetStats(nullptr, &reports);
1745
sakale5ba44e2016-10-26 14:09:241746 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
1747 ExtractSsrcStatsValue(reports,
1748 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 12:53:451749 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
1750 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 14:09:241751}
1752
Mirko Bonadeic84f6612019-01-31 11:20:571753INSTANTIATE_TEST_SUITE_P(HasStream, StatsCollectorTrackTest, ::testing::Bool());
Harald Alvestrand75ceef22018-01-04 14:26:131754
guoweis@webrtc.org950c5182014-12-16 23:01:311755} // namespace webrtc