blob: 56d4fca14da29afe21845bea4c72e675babe9272 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11#include <stdio.h>
12
deadbeefcbecd352015-09-23 11:50:27 -070013#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
deadbeefcbecd352015-09-23 11:50:27 -070015
ossu7bb87ee2017-01-23 04:56:25 -080016#include "webrtc/pc/statscollector.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
Henrik Kjellander15583c12016-02-10 10:53:12 +010018#include "webrtc/api/mediastreaminterface.h"
skvlad11a9cbf2016-10-07 11:53:05 -070019#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080020#include "webrtc/media/base/fakemediaengine.h"
hbosb24b1ce2016-08-16 01:19:43 -070021#include "webrtc/media/base/test/mock_mediachannel.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010022#include "webrtc/pc/channelmanager.h"
ossu7bb87ee2017-01-23 04:56:25 -080023#include "webrtc/pc/mediastream.h"
24#include "webrtc/pc/mediastreamtrack.h"
25#include "webrtc/pc/peerconnection.h"
26#include "webrtc/pc/peerconnectionfactory.h"
27#include "webrtc/pc/test/fakedatachannelprovider.h"
28#include "webrtc/pc/test/fakevideotracksource.h"
29#include "webrtc/pc/test/mock_peerconnection.h"
30#include "webrtc/pc/test/mock_webrtcsession.h"
31#include "webrtc/pc/videotrack.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020032#include "webrtc/rtc_base/base64.h"
33#include "webrtc/rtc_base/fakesslidentity.h"
34#include "webrtc/rtc_base/gunit.h"
35#include "webrtc/rtc_base/network.h"
36#include "webrtc/rtc_base/stringencode.h"
kwibergac9f8762016-09-30 22:29:43 -070037#include "webrtc/test/gmock.h"
38#include "webrtc/test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039
40using testing::_;
41using testing::DoAll;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000042using testing::Field;
hbosdf6075a2016-12-19 04:58:02 -080043using testing::Invoke;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044using testing::Return;
45using testing::ReturnNull;
deadbeefab9b2d12015-10-14 11:33:11 -070046using testing::ReturnRef;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047using testing::SetArgPointee;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000048using webrtc::PeerConnectionInterface;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000049using webrtc::StatsReport;
50using webrtc::StatsReports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051
deadbeef7af91dd2016-12-13 11:29:11 -080052namespace {
deadbeefac22f702017-01-12 21:59:29 -080053const bool kDefaultRtcpMuxRequired = true;
deadbeef7af91dd2016-12-13 11:29:11 -080054const bool kDefaultSrtpRequired = true;
55}
56
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057namespace cricket {
58
59class ChannelManager;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
61} // namespace cricket
62
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000063namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064
tkchin7d06a8c2016-04-04 14:10:43 -070065namespace internal {
66// This value comes from openssl/tls1.h
67static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
68} // namespace internal
69
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070// Error return values
71const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072
wu@webrtc.org97077a32013-10-25 21:18:33 +000073// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000074const char kLocalTrackId[] = "local_track_id";
75const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020076const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000077
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000078class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
79 public:
80 FakeAudioProcessor() {}
81 ~FakeAudioProcessor() {}
82
83 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000084 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000085 stats->typing_noise_detected = true;
86 stats->echo_return_loss = 2;
87 stats->echo_return_loss_enhancement = 3;
88 stats->echo_delay_median_ms = 4;
89 stats->aec_quality_min = 5.1f;
90 stats->echo_delay_std_ms = 6;
91 }
92};
93
xians@webrtc.org4cb01282014-06-12 14:57:05 +000094class FakeAudioTrack
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000095 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
96 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +000097 explicit FakeAudioTrack(const std::string& id)
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000098 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000099 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000100 std::string kind() const override { return "audio"; }
101 webrtc::AudioSourceInterface* GetSource() const override { return NULL; }
102 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
103 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
104 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000105 *level = 1;
106 return true;
107 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000108 rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
109 override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000110 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000111 }
112
113 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000114 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000115};
116
zhihuang6ba3b192016-05-13 11:46:35 -0700117// This fake audio processor is used to verify that the undesired initial values
118// (-1) will be filtered out.
119class FakeAudioProcessorWithInitValue : public webrtc::AudioProcessorInterface {
120 public:
121 FakeAudioProcessorWithInitValue() {}
122 ~FakeAudioProcessorWithInitValue() {}
123
124 private:
125 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
126 stats->typing_noise_detected = false;
127 stats->echo_return_loss = -100;
128 stats->echo_return_loss_enhancement = -100;
129 stats->echo_delay_median_ms = -1;
130 stats->aec_quality_min = -1.0f;
131 stats->echo_delay_std_ms = -1;
132 }
133};
134
135class FakeAudioTrackWithInitValue
136 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
137 public:
138 explicit FakeAudioTrackWithInitValue(const std::string& id)
139 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
140 processor_(
141 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
142 std::string kind() const override { return "audio"; }
143 webrtc::AudioSourceInterface* GetSource() const override { return NULL; }
144 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
145 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
146 bool GetSignalLevel(int* level) override {
147 *level = 1;
148 return true;
149 }
150 rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
151 override {
152 return processor_;
153 }
154
155 private:
156 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
157};
158
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000159bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000160 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000161 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000162 const StatsReport::Value* v = report->FindValue(name);
163 if (!v)
164 return false;
165 *value = v->ToString();
166 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000167}
168
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000169std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000170 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000171 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000172 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000173 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000174 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000175 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 }
177
178 return kNotFound;
179}
180
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000181StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
182 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000183 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000184 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000185 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000186 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000187
188 // This has assumptions about how the ID is constructed. As is, this is
189 // OK since this is for testing purposes only, but if we ever need this
190 // in production, we should add a generic method that does this.
191 size_t index = value.find('_');
192 EXPECT_NE(index, std::string::npos);
193 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000194 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000195
196 id = StatsReport::NewTypedId(type, value.substr(index + 1));
197 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000198 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000199}
200
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000201StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
202 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000203}
204
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205// Finds the |n|-th report of type |type| in |reports|.
206// |n| starts from 1 for finding the first report.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000207const StatsReport* FindNthReportByType(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000208 const StatsReports& reports, const StatsReport::StatsType& type, int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000210 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 n--;
212 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000213 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 }
215 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000216 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217}
218
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000219const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000220 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000221 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000222 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000223 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000225 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226}
227
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000228std::string ExtractSsrcStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000229 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000230 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000231}
232
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000233std::string ExtractBweStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000234 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000236 StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237}
238
wu@webrtc.org4551b792013-10-09 15:37:36 +0000239std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000240 return rtc::SSLIdentity::DerToPem(
241 rtc::kPemTypeCertificate,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000242 reinterpret_cast<const unsigned char*>(der.c_str()),
243 der.length());
244}
245
246std::vector<std::string> DersToPems(
247 const std::vector<std::string>& ders) {
248 std::vector<std::string> pems(ders.size());
249 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
250 return pems;
251}
252
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000253void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000254 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000255 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000256 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000257 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000258 size_t i = 0;
259 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000260 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000261 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000262
wu@webrtc.org4551b792013-10-09 15:37:36 +0000263 std::string der_base64;
264 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000265 report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000266 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000267 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000268
269 std::string fingerprint_algorithm;
270 EXPECT_TRUE(GetValue(
271 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000272 StatsReport::kStatsValueNameFingerprintAlgorithm,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000273 &fingerprint_algorithm));
274 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000275 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000276 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
277
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000278 std::string fingerprint;
279 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
280 &fingerprint));
281 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000282
wu@webrtc.org4551b792013-10-09 15:37:36 +0000283 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000284 std::string issuer_id;
285 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId,
286 &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000287 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000288 }
289
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000290 cert_id = IdFromCertIdString(issuer_id);
291 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000292 }
293 EXPECT_EQ(ders.size(), i);
294}
295
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000296void VerifyVoiceReceiverInfoReport(
297 const StatsReport* report,
298 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000299 std::string value_in_report;
300 EXPECT_TRUE(GetValue(
301 report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000302 EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000303 EXPECT_TRUE(GetValue(
304 report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200305 EXPECT_EQ(rtc::ToString<int64_t>(info.bytes_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000306 EXPECT_TRUE(GetValue(
307 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000308 EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000309 EXPECT_TRUE(GetValue(
310 report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000312 EXPECT_TRUE(GetValue(
313 report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
314 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000315 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000316 value_in_report);
317 EXPECT_TRUE(GetValue(
318 report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000319 EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000320 EXPECT_TRUE(GetValue(
321 report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000322 EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000323 EXPECT_TRUE(GetValue(
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000324 report, StatsReport::kStatsValueNameSpeechExpandRate, &value_in_report));
325 EXPECT_EQ(rtc::ToString<float>(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200326 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
327 &value_in_report));
328 EXPECT_EQ(rtc::ToString<float>(info.accelerate_rate), value_in_report);
329 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
330 &value_in_report));
331 EXPECT_EQ(rtc::ToString<float>(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000332 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
333 &value_in_report));
334 EXPECT_EQ(rtc::ToString<float>(info.secondary_decoded_rate), value_in_report);
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200335 EXPECT_TRUE(GetValue(report,
336 StatsReport::kStatsValueNameSecondaryDiscardedRate,
337 &value_in_report));
338 EXPECT_EQ(rtc::ToString<float>(info.secondary_discarded_rate),
339 value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000340 EXPECT_TRUE(GetValue(
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000341 report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000342 EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000343 EXPECT_TRUE(GetValue(
344 report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000345 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000346 value_in_report);
347 EXPECT_TRUE(GetValue(
348 report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000349 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000350 value_in_report);
351 EXPECT_TRUE(GetValue(
352 report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000353 EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000354 EXPECT_TRUE(GetValue(
355 report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000356 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000357 EXPECT_TRUE(GetValue(
358 report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000359 EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000360 EXPECT_TRUE(GetValue(
361 report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000362 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
henrik.lundin63489782016-09-20 01:47:12 -0700363 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingMutedOutput,
364 &value_in_report));
365 EXPECT_EQ(rtc::ToString<int>(info.decoding_muted_output), value_in_report);
366 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameCodecName,
367 &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000368}
369
370
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000371void VerifyVoiceSenderInfoReport(const StatsReport* report,
372 const cricket::VoiceSenderInfo& sinfo) {
373 std::string value_in_report;
374 EXPECT_TRUE(GetValue(
375 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
376 EXPECT_EQ(sinfo.codec_name, value_in_report);
377 EXPECT_TRUE(GetValue(
378 report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200379 EXPECT_EQ(rtc::ToString<int64_t>(sinfo.bytes_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000380 EXPECT_TRUE(GetValue(
381 report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000382 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000383 EXPECT_TRUE(GetValue(
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000384 report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000385 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000386 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000387 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000388 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000389 EXPECT_TRUE(GetValue(
390 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000391 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000392 EXPECT_TRUE(GetValue(
393 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000394 EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000395 EXPECT_TRUE(GetValue(
396 report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
397 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000398 EXPECT_EQ(rtc::ToString<float>(sinfo.aec_quality_min), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000399 EXPECT_TRUE(GetValue(
400 report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000401 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_median_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000402 value_in_report);
403 EXPECT_TRUE(GetValue(
404 report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000405 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_std_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000406 value_in_report);
407 EXPECT_TRUE(GetValue(
408 report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000409 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000410 value_in_report);
411 EXPECT_TRUE(GetValue(
412 report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
413 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000414 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss_enhancement),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000415 value_in_report);
ivoc8c63a822016-10-21 04:10:03 -0700416 EXPECT_TRUE(GetValue(report,
417 StatsReport::kStatsValueNameResidualEchoLikelihood,
418 &value_in_report));
419 EXPECT_EQ(rtc::ToString<float>(sinfo.residual_echo_likelihood),
420 value_in_report);
ivoc4e477a12017-01-15 08:29:46 -0800421 EXPECT_TRUE(GetValue(
422 report, StatsReport::kStatsValueNameResidualEchoLikelihoodRecentMax,
423 &value_in_report));
424 EXPECT_EQ(rtc::ToString<float>(sinfo.residual_echo_likelihood_recent_max),
425 value_in_report);
ivoc8c63a822016-10-21 04:10:03 -0700426 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
427 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000428 EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000429 EXPECT_TRUE(GetValue(
430 report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
431 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
432 EXPECT_EQ(typing_detected, value_in_report);
433}
434
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000435// Helper methods to avoid duplication of code.
436void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
437 voice_sender_info->add_ssrc(kSsrcOfTrack);
438 voice_sender_info->codec_name = "fake_codec";
439 voice_sender_info->bytes_sent = 100;
440 voice_sender_info->packets_sent = 101;
441 voice_sender_info->rtt_ms = 102;
442 voice_sender_info->fraction_lost = 103;
443 voice_sender_info->jitter_ms = 104;
444 voice_sender_info->packets_lost = 105;
445 voice_sender_info->ext_seqnum = 106;
446 voice_sender_info->audio_level = 107;
447 voice_sender_info->echo_return_loss = 108;
448 voice_sender_info->echo_return_loss_enhancement = 109;
449 voice_sender_info->echo_delay_median_ms = 110;
450 voice_sender_info->echo_delay_std_ms = 111;
451 voice_sender_info->aec_quality_min = 112.0f;
452 voice_sender_info->typing_noise_detected = false;
453}
454
455void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700456 AudioTrackInterface* audio_track,
457 cricket::VoiceSenderInfo* voice_sender_info) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000458 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
459 webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
460 audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats);
461 voice_sender_info->typing_noise_detected =
462 audio_processor_stats.typing_noise_detected;
463 voice_sender_info->echo_return_loss = audio_processor_stats.echo_return_loss;
464 voice_sender_info->echo_return_loss_enhancement =
465 audio_processor_stats.echo_return_loss_enhancement;
466 voice_sender_info->echo_delay_median_ms =
467 audio_processor_stats.echo_delay_median_ms;
468 voice_sender_info->aec_quality_min = audio_processor_stats.aec_quality_min;
469 voice_sender_info->echo_delay_std_ms =
470 audio_processor_stats.echo_delay_std_ms;
471}
472
473void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
474 voice_receiver_info->add_ssrc(kSsrcOfTrack);
475 voice_receiver_info->bytes_rcvd = 110;
476 voice_receiver_info->packets_rcvd = 111;
477 voice_receiver_info->packets_lost = 112;
478 voice_receiver_info->fraction_lost = 113;
479 voice_receiver_info->packets_lost = 114;
480 voice_receiver_info->ext_seqnum = 115;
481 voice_receiver_info->jitter_ms = 116;
482 voice_receiver_info->jitter_buffer_ms = 117;
483 voice_receiver_info->jitter_buffer_preferred_ms = 118;
484 voice_receiver_info->delay_estimate_ms = 119;
485 voice_receiver_info->audio_level = 120;
486 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000487 voice_receiver_info->speech_expand_rate = 122;
488 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200489 voice_receiver_info->accelerate_rate = 124;
490 voice_receiver_info->preemptive_expand_rate = 125;
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200491 voice_receiver_info->secondary_discarded_rate = 126;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000492}
493
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000494class StatsCollectorForTest : public webrtc::StatsCollector {
495 public:
deadbeefab9b2d12015-10-14 11:33:11 -0700496 explicit StatsCollectorForTest(PeerConnection* pc)
497 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000498
499 double GetTimeNow() override {
500 return time_now_;
501 }
502
503 private:
504 double time_now_;
505};
506
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000507class StatsCollectorTest : public testing::Test {
508 protected:
509 StatsCollectorTest()
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200510 : worker_thread_(rtc::Thread::Current()),
511 network_thread_(rtc::Thread::Current()),
512 media_engine_(new cricket::FakeMediaEngine()),
deadbeef112b2e92017-02-10 20:13:37 -0800513 channel_manager_(new cricket::ChannelManager(
514 std::unique_ptr<cricket::MediaEngineInterface>(media_engine_),
515 worker_thread_,
516 network_thread_)),
nisseeaabdf62017-05-05 02:23:02 -0700517
518 session_(channel_manager_.get(), cricket::MediaConfig()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000519 // By default, we ignore session GetStats calls.
hbosdf6075a2016-12-19 04:58:02 -0800520 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
deadbeefab9b2d12015-10-14 11:33:11 -0700521 // Add default returns for mock classes.
522 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
523 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
524 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
525 EXPECT_CALL(pc_, sctp_data_channels())
526 .WillRepeatedly(ReturnRef(data_channels_));
hbos84abeb12017-01-16 06:16:44 -0800527 EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
528 std::vector<rtc::scoped_refptr<RtpSenderInterface>>()));
529 EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
530 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531 }
532
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000533 ~StatsCollectorTest() {}
534
wu@webrtc.org97077a32013-10-25 21:18:33 +0000535 // This creates a standard setup with a transport called "trspname"
536 // having one transport channel
537 // and the specified virtual connection name.
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000538 void InitSessionStats(const std::string& vc_name) {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000539 const std::string kTransportName("trspname");
540 cricket::TransportStats transport_stats;
541 cricket::TransportChannelStats channel_stats;
542 channel_stats.component = 1;
deadbeefcbecd352015-09-23 11:50:27 -0700543 transport_stats.transport_name = kTransportName;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000544 transport_stats.channel_stats.push_back(channel_stats);
545
546 session_stats_.transport_stats[kTransportName] = transport_stats;
547 session_stats_.proxy_to_transport[vc_name] = kTransportName;
548 }
549
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000550 // Adds a outgoing video track with a given SSRC into the stats.
551 void AddOutgoingVideoTrackStats() {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000552 stream_ = webrtc::MediaStream::Create("streamlabel");
nisseaf510af2016-03-21 08:20:42 -0700553 track_ = webrtc::VideoTrack::Create(kLocalTrackId,
perkj773be362017-07-31 23:22:01 -0700554 webrtc::FakeVideoTrackSource::Create(),
555 rtc::Thread::Current());
wu@webrtc.org97077a32013-10-25 21:18:33 +0000556 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000557 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
558 .WillRepeatedly(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000559 }
560
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000561 // Adds a incoming video track with a given SSRC into the stats.
562 void AddIncomingVideoTrackStats() {
563 stream_ = webrtc::MediaStream::Create("streamlabel");
nisseaf510af2016-03-21 08:20:42 -0700564 track_ = webrtc::VideoTrack::Create(kRemoteTrackId,
perkj773be362017-07-31 23:22:01 -0700565 webrtc::FakeVideoTrackSource::Create(),
566 rtc::Thread::Current());
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000567 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000568 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000569 .WillRepeatedly(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000570 }
571
572 // Adds a outgoing audio track with a given SSRC into the stats.
573 void AddOutgoingAudioTrackStats() {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000574 if (stream_ == NULL)
575 stream_ = webrtc::MediaStream::Create("streamlabel");
576
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000577 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000578 kLocalTrackId);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000579 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000580 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000581 .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000582 }
583
584 // Adds a incoming audio track with a given SSRC into the stats.
585 void AddIncomingAudioTrackStats() {
586 if (stream_ == NULL)
587 stream_ = webrtc::MediaStream::Create("streamlabel");
588
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000589 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000590 kRemoteTrackId);
591 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000592 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000593 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
594 }
595
deadbeefab9b2d12015-10-14 11:33:11 -0700596 void AddDataChannel(cricket::DataChannelType type,
597 const std::string& label,
598 int id) {
599 InternalDataChannelInit config;
600 config.id = id;
601
602 data_channels_.push_back(DataChannel::Create(
603 &data_channel_provider_, cricket::DCT_SCTP, label, config));
604 }
605
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000606 StatsReport* AddCandidateReport(StatsCollector* collector,
607 const cricket::Candidate& candidate,
608 bool local) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000609 return collector->AddCandidateReport(candidate, local);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000610 }
611
xians@webrtc.org01bda202014-07-09 07:38:38 +0000612 void SetupAndVerifyAudioTrackStats(
613 FakeAudioTrack* audio_track,
614 webrtc::MediaStream* stream,
615 webrtc::StatsCollector* stats,
616 cricket::VoiceChannel* voice_channel,
617 const std::string& vc_name,
618 MockVoiceMediaChannel* media_channel,
619 cricket::VoiceSenderInfo* voice_sender_info,
620 cricket::VoiceReceiverInfo* voice_receiver_info,
621 cricket::VoiceMediaInfo* stats_read,
622 StatsReports* reports) {
623 // A track can't have both sender report and recv report at the same time
624 // for now, this might change in the future though.
nissec8ee8822017-01-18 07:20:55 -0800625 EXPECT_TRUE((voice_sender_info == NULL) ^ (voice_receiver_info == NULL));
xians@webrtc.org01bda202014-07-09 07:38:38 +0000626
627 // Instruct the session to return stats containing the transport channel.
628 InitSessionStats(vc_name);
hbosdf6075a2016-12-19 04:58:02 -0800629 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
630 [this](const ChannelNamePairs&) {
631 return std::unique_ptr<SessionStats>(
632 new SessionStats(session_stats_));
633 }));
xians@webrtc.org01bda202014-07-09 07:38:38 +0000634
635 // Constructs an ssrc stats update.
636 if (voice_sender_info)
637 stats_read->senders.push_back(*voice_sender_info);
638 if (voice_receiver_info)
639 stats_read->receivers.push_back(*voice_receiver_info);
640
641 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(
642 Return(voice_channel));
643 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
644 EXPECT_CALL(*media_channel, GetStats(_))
645 .WillOnce(DoAll(SetArgPointee<0>(*stats_read), Return(true)));
646
647 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000648 stats->ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +0000649 stats->GetStats(NULL, reports);
650
651 // Verify the existence of the track report.
652 const StatsReport* report = FindNthReportByType(
653 *reports, StatsReport::kStatsReportTypeSsrc, 1);
654 EXPECT_FALSE(report == NULL);
jbauchbe24c942015-06-22 15:06:43 -0700655 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000656 std::string track_id = ExtractSsrcStatsValue(
657 *reports, StatsReport::kStatsValueNameTrackId);
658 EXPECT_EQ(audio_track->id(), track_id);
659 std::string ssrc_id = ExtractSsrcStatsValue(
660 *reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200661 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000662
fippobec70ab2016-01-28 01:27:15 -0800663 std::string media_type = ExtractSsrcStatsValue(*reports,
664 StatsReport::kStatsValueNameMediaType);
665 EXPECT_EQ("audio", media_type);
666
xians@webrtc.org01bda202014-07-09 07:38:38 +0000667 // Verifies the values in the track report.
668 if (voice_sender_info) {
669 UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info);
670 VerifyVoiceSenderInfoReport(report, *voice_sender_info);
671 }
672 if (voice_receiver_info) {
673 VerifyVoiceReceiverInfoReport(report, *voice_receiver_info);
674 }
675
676 // Verify we get the same result by passing a track to GetStats().
677 StatsReports track_reports; // returned values.
678 stats->GetStats(audio_track, &track_reports);
679 const StatsReport* track_report = FindNthReportByType(
680 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
681 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700682 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000683 track_id = ExtractSsrcStatsValue(track_reports,
684 StatsReport::kStatsValueNameTrackId);
685 EXPECT_EQ(audio_track->id(), track_id);
686 ssrc_id = ExtractSsrcStatsValue(track_reports,
687 StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200688 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000689 if (voice_sender_info)
690 VerifyVoiceSenderInfoReport(track_report, *voice_sender_info);
691 if (voice_receiver_info)
692 VerifyVoiceReceiverInfoReport(track_report, *voice_receiver_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000693 }
694
kwibergb4d01c42016-04-06 05:15:06 -0700695 void TestCertificateReports(
696 const rtc::FakeSSLCertificate& local_cert,
697 const std::vector<std::string>& local_ders,
kwibergd1fe2812016-04-27 06:47:29 -0700698 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert,
kwibergb4d01c42016-04-06 05:15:06 -0700699 const std::vector<std::string>& remote_ders) {
deadbeefab9b2d12015-10-14 11:33:11 -0700700 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000701
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000702 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000703
704 // Fake stats to process.
705 cricket::TransportChannelStats channel_stats;
706 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800707 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700708 channel_stats.ssl_cipher_suite =
709 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000710
711 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -0700712 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +0000713 transport_stats.channel_stats.push_back(channel_stats);
714
deadbeefd59daf82015-10-14 15:02:44 -0700715 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -0700716 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +0000717 transport_stats;
718
deadbeefcbecd352015-09-23 11:50:27 -0700719 // Fake certificate to report
Henrik Boströmd8281982015-08-27 10:12:24 +0200720 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
jbauch555604a2016-04-26 03:13:22 -0700721 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800722 new rtc::FakeSSLIdentity(local_cert))));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000723
724 // Configure MockWebRtcSession
deadbeefcbecd352015-09-23 11:50:27 -0700725 EXPECT_CALL(session_,
726 GetLocalCertificate(transport_stats.transport_name, _))
727 .WillOnce(DoAll(SetArgPointee<1>(local_certificate), Return(true)));
kwibergb4d01c42016-04-06 05:15:06 -0700728 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(
729 transport_stats.transport_name))
730 .WillOnce(Return(remote_cert.release()));
hbosdf6075a2016-12-19 04:58:02 -0800731 EXPECT_CALL(session_, GetStats(_)).WillOnce(Invoke(
732 [&session_stats](const ChannelNamePairs&) {
733 return std::unique_ptr<SessionStats>(
734 new SessionStats(session_stats));
735 }));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000736
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000737 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000738
739 stats.GetStats(NULL, &reports);
740
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000741 const StatsReport* channel_report = FindNthReportByType(
742 reports, StatsReport::kStatsReportTypeComponent, 1);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000743 EXPECT_TRUE(channel_report != NULL);
744
745 // Check local certificate chain.
746 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000747 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000748 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000749 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000750 if (local_ders.size() > 0) {
751 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000752 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
753 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000754 } else {
755 EXPECT_EQ(kNotFound, local_certificate_id);
756 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000757
758 // Check remote certificate chain.
759 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000760 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000761 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000762 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000763 if (remote_ders.size() > 0) {
764 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000765 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
766 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000767 } else {
768 EXPECT_EQ(kNotFound, remote_certificate_id);
769 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000770
771 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800772 std::string dtls_cipher_suite =
773 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
774 StatsReport::kStatsValueNameDtlsCipher);
775 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700776 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800777 dtls_cipher_suite);
778 std::string srtp_crypto_suite =
779 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
780 StatsReport::kStatsValueNameSrtpCipher);
781 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
782 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000783 }
wu@webrtc.org97077a32013-10-25 21:18:33 +0000784
skvlad11a9cbf2016-10-07 11:53:05 -0700785 webrtc::RtcEventLogNullImpl event_log_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200786 rtc::Thread* const worker_thread_;
787 rtc::Thread* const network_thread_;
deadbeef112b2e92017-02-10 20:13:37 -0800788 // |media_engine_| is actually owned by |channel_manager_|.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789 cricket::FakeMediaEngine* media_engine_;
kwibergd1fe2812016-04-27 06:47:29 -0700790 std::unique_ptr<cricket::ChannelManager> channel_manager_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 MockWebRtcSession session_;
deadbeefab9b2d12015-10-14 11:33:11 -0700792 MockPeerConnection pc_;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000793 FakeDataChannelProvider data_channel_provider_;
deadbeefd59daf82015-10-14 15:02:44 -0700794 SessionStats session_stats_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000795 rtc::scoped_refptr<webrtc::MediaStream> stream_;
796 rtc::scoped_refptr<webrtc::VideoTrack> track_;
797 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
deadbeefab9b2d12015-10-14 11:33:11 -0700798 std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799};
800
zhihuang6ba3b192016-05-13 11:46:35 -0700801TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
802 const std::string label = "hacks";
803 // The data channel id is from the Config which is -1 initially.
804 const int id = -1;
805 const std::string state = DataChannelInterface::DataStateString(
806 DataChannelInterface::DataState::kConnecting);
807
808 AddDataChannel(cricket::DCT_SCTP, label, id);
809 StatsCollectorForTest stats(&pc_);
810
811 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
812
813 StatsReports reports;
814 stats.GetStats(NULL, &reports);
815
816 const StatsReport* report =
817 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
818
819 std::string value_in_report;
820 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
821 &value_in_report));
822}
823
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000824// Verify that ExtractDataInfo populates reports.
825TEST_F(StatsCollectorTest, ExtractDataInfo) {
826 const std::string label = "hacks";
827 const int id = 31337;
828 const std::string state = DataChannelInterface::DataStateString(
829 DataChannelInterface::DataState::kConnecting);
830
deadbeefab9b2d12015-10-14 11:33:11 -0700831 AddDataChannel(cricket::DCT_SCTP, label, id);
832 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000833
834 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
835
836 StatsReports reports;
837 stats.GetStats(NULL, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000838
839 const StatsReport* report =
840 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
841
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000842 StatsReport::Id reportId = StatsReport::NewTypedIntId(
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000843 StatsReport::kStatsReportTypeDataChannel, id);
844
845 EXPECT_TRUE(reportId->Equals(report->id()));
846
847 EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000848 EXPECT_EQ(label, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
849 reports,
850 StatsReport::kStatsValueNameLabel));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200851 EXPECT_EQ(rtc::ToString<int64_t>(id),
852 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000853 StatsReport::kStatsValueNameDataChannelId));
854 EXPECT_EQ(state, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
855 reports,
856 StatsReport::kStatsValueNameState));
857 EXPECT_EQ("", ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
858 reports,
859 StatsReport::kStatsValueNameProtocol));
860}
861
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862// This test verifies that 64-bit counters are passed successfully.
863TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
deadbeefab9b2d12015-10-14 11:33:11 -0700864 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000865
deadbeefcbecd352015-09-23 11:50:27 -0700866 EXPECT_CALL(session_, GetLocalCertificate(_, _))
867 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -0700868 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
869 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -0700870
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000871 const char kVideoChannelName[] = "video";
872
873 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -0800874 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
875 [this](const ChannelNamePairs&) {
876 return std::unique_ptr<SessionStats>(
877 new SessionStats(session_stats_));
878 }));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000879
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000880 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -0800881 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -0800882 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -0800883 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000884 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 cricket::VideoSenderInfo video_sender_info;
886 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200888 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889 const std::string kBytesSentString("12345678901234");
890
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000891 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000892 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893
894 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000895 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896 video_sender_info.bytes_sent = kBytesSent;
897 stats_read.senders.push_back(video_sender_info);
898
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000899 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
900 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000901 EXPECT_CALL(*media_channel, GetStats(_))
902 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000903 Return(true)));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000904 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000906 std::string result = ExtractSsrcStatsValue(reports,
907 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 EXPECT_EQ(kBytesSentString, result);
909}
910
Alex Narest42308f62017-06-19 17:58:12 +0200911// Test that audio BWE information is reported via stats.
912TEST_F(StatsCollectorTest, AudioBandwidthEstimationInfoIsReported) {
913 StatsCollectorForTest stats(&pc_);
914
915 EXPECT_CALL(session_, GetLocalCertificate(_, _))
916 .WillRepeatedly(Return(false));
917 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
918 .WillRepeatedly(Return(nullptr));
919
920 const char kAudioChannelName[] = "audio";
921
922 InitSessionStats(kAudioChannelName);
923 EXPECT_CALL(session_, GetStats(_))
924 .WillRepeatedly(Invoke([this](const ChannelNamePairs&) {
925 return std::unique_ptr<SessionStats>(new SessionStats(session_stats_));
926 }));
927
928 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
929 cricket::VoiceChannel voice_channel(
930 worker_thread_, network_thread_, nullptr, nullptr, media_channel,
931 kAudioChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
932
933 StatsReports reports; // returned values.
934 cricket::VoiceSenderInfo voice_sender_info;
935 cricket::VoiceMediaInfo stats_read;
936 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
937 // BWE.
938 const int64_t kBytesSent = 12345678901234LL;
939 const std::string kBytesSentString("12345678901234");
940
941 AddOutgoingAudioTrackStats();
942 stats.AddStream(stream_);
943
944 // Construct a stats value to read.
945 voice_sender_info.add_ssrc(1234);
946 voice_sender_info.bytes_sent = kBytesSent;
947 stats_read.senders.push_back(voice_sender_info);
948
949 webrtc::Call::Stats call_stats;
950 const int kSendBandwidth = 1234567;
951 const int kRecvBandwidth = 12345678;
952 const int kPacerDelay = 123;
953 call_stats.send_bandwidth_bps = kSendBandwidth;
954 call_stats.recv_bandwidth_bps = kRecvBandwidth;
955 call_stats.pacer_delay_ms = kPacerDelay;
956 EXPECT_CALL(session_, GetCallStats()).WillRepeatedly(Return(call_stats));
957 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
958 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
959 EXPECT_CALL(*media_channel, GetStats(_))
960 .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
961
962 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
963 stats.GetStats(NULL, &reports);
964 std::string result =
965 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameBytesSent);
966 EXPECT_EQ(kBytesSentString, result);
967 result = ExtractBweStatsValue(
968 reports, StatsReport::kStatsValueNameAvailableSendBandwidth);
969 EXPECT_EQ(rtc::ToString(kSendBandwidth), result);
970 result = ExtractBweStatsValue(
971 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth);
972 EXPECT_EQ(rtc::ToString(kRecvBandwidth), result);
973 result =
974 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay);
975 EXPECT_EQ(rtc::ToString(kPacerDelay), result);
976}
977
978// Test that video BWE information is reported via stats.
979TEST_F(StatsCollectorTest, VideoBandwidthEstimationInfoIsReported) {
deadbeefab9b2d12015-10-14 11:33:11 -0700980 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000981
deadbeefcbecd352015-09-23 11:50:27 -0700982 EXPECT_CALL(session_, GetLocalCertificate(_, _))
983 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -0700984 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
985 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -0700986
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000987 const char kVideoChannelName[] = "video";
988
989 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -0800990 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
991 [this](const ChannelNamePairs&) {
992 return std::unique_ptr<SessionStats>(
993 new SessionStats(session_stats_));
994 }));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000995
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000996 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -0800997 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -0800998 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -0800999 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001000
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001001 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002 cricket::VideoSenderInfo video_sender_info;
1003 cricket::VideoMediaInfo stats_read;
1004 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
1005 // BWE.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001006 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001007 const std::string kBytesSentString("12345678901234");
1008
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001009 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001010 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011
1012 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001013 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014 video_sender_info.bytes_sent = kBytesSent;
1015 stats_read.senders.push_back(video_sender_info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016
stefanf79ade12017-06-02 06:44:03 -07001017 webrtc::Call::Stats call_stats;
1018 const int kSendBandwidth = 1234567;
1019 const int kRecvBandwidth = 12345678;
1020 const int kPacerDelay = 123;
1021 call_stats.send_bandwidth_bps = kSendBandwidth;
1022 call_stats.recv_bandwidth_bps = kRecvBandwidth;
1023 call_stats.pacer_delay_ms = kPacerDelay;
1024 EXPECT_CALL(session_, GetCallStats()).WillRepeatedly(Return(call_stats));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001025 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1026 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001027 EXPECT_CALL(*media_channel, GetStats(_))
1028 .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001029
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001030 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001032 std::string result = ExtractSsrcStatsValue(reports,
1033 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034 EXPECT_EQ(kBytesSentString, result);
stefanf79ade12017-06-02 06:44:03 -07001035 result = ExtractBweStatsValue(
1036 reports, StatsReport::kStatsValueNameAvailableSendBandwidth);
1037 EXPECT_EQ(rtc::ToString(kSendBandwidth), result);
1038 result = ExtractBweStatsValue(
1039 reports, StatsReport::kStatsValueNameAvailableReceiveBandwidth);
1040 EXPECT_EQ(rtc::ToString(kRecvBandwidth), result);
1041 result =
1042 ExtractBweStatsValue(reports, StatsReport::kStatsValueNameBucketDelay);
1043 EXPECT_EQ(rtc::ToString(kPacerDelay), result);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044}
1045
1046// This test verifies that an object of type "googSession" always
1047// exists in the returned stats.
1048TEST_F(StatsCollectorTest, SessionObjectExists) {
deadbeefab9b2d12015-10-14 11:33:11 -07001049 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001050
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001051 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001052 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001054 const StatsReport* session_report = FindNthReportByType(
1055 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001056 EXPECT_FALSE(session_report == NULL);
1057}
1058
1059// This test verifies that only one object of type "googSession" exists
1060// in the returned stats.
1061TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
deadbeefab9b2d12015-10-14 11:33:11 -07001062 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001063
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001064 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001065 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1066 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001068 const StatsReport* session_report = FindNthReportByType(
1069 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001070 EXPECT_FALSE(session_report == NULL);
1071 session_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001072 reports, StatsReport::kStatsReportTypeSession, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073 EXPECT_EQ(NULL, session_report);
1074}
1075
1076// This test verifies that the empty track report exists in the returned stats
1077// without calling StatsCollector::UpdateStats.
1078TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
deadbeefab9b2d12015-10-14 11:33:11 -07001079 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001080
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001081 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -08001082 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001083 worker_thread_, network_thread_, nullptr, media_channel, "video",
deadbeefac22f702017-01-12 21:59:29 -08001084 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001085 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001086 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001088 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001089 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001090 stats.GetStats(NULL, &reports);
1091 EXPECT_EQ((size_t)1, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001092 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -07001093 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001094
1095 std::string trackValue =
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001096 ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001097 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001098 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001099 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001100}
1101
1102// This test verifies that the empty track report exists in the returned stats
1103// when StatsCollector::UpdateStats is called with ssrc stats.
1104TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
deadbeefab9b2d12015-10-14 11:33:11 -07001105 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001106
deadbeefcbecd352015-09-23 11:50:27 -07001107 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1108 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001109 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1110 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001111
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001112 const char kVideoChannelName[] = "video";
1113 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -08001114 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1115 [this](const ChannelNamePairs&) {
1116 return std::unique_ptr<SessionStats>(
1117 new SessionStats(session_stats_));
1118 }));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001119
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001120 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -08001121 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001122 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001123 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001124 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001125 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001127 // Constructs an ssrc stats update.
1128 cricket::VideoSenderInfo video_sender_info;
1129 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001130 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001131
1132 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001133 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134 video_sender_info.bytes_sent = kBytesSent;
1135 stats_read.senders.push_back(video_sender_info);
1136
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001137 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1138 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001139 EXPECT_CALL(*media_channel, GetStats(_))
1140 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001141 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001143 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001144 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001145 stats.GetStats(NULL, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001146 // |reports| should contain at least one session report, one track report,
1147 // and one ssrc report.
1148 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001149 const StatsReport* track_report = FindNthReportByType(
1150 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001151 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001152
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001153 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001154 reports.clear();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001155 stats.GetStats(track_, &reports);
1156 // |reports| should contain at least one session report, one track report,
1157 // and one ssrc report.
1158 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159 track_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001160 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001161 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001162 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001163
1164 std::string ssrc_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001165 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001166 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001167
1168 std::string track_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001169 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001170 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001171
1172 std::string media_type = ExtractSsrcStatsValue(reports,
1173 StatsReport::kStatsValueNameMediaType);
1174 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001175}
1176
1177// This test verifies that an SSRC object has the identifier of a Transport
1178// stats object, and that this transport stats object exists in stats.
1179TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
deadbeefab9b2d12015-10-14 11:33:11 -07001180 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001181
deadbeefcbecd352015-09-23 11:50:27 -07001182 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1183 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001184 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1185 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001186
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001187 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001188 // The transport_name known by the video channel.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001189 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001190 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001191 worker_thread_, network_thread_, nullptr, media_channel, kVcName,
deadbeefac22f702017-01-12 21:59:29 -08001192 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001193 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001194 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001195
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001196 // Constructs an ssrc stats update.
1197 cricket::VideoSenderInfo video_sender_info;
1198 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001199 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001200
1201 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001202 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001203 video_sender_info.bytes_sent = kBytesSent;
1204 stats_read.senders.push_back(video_sender_info);
1205
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001206 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1207 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001208 EXPECT_CALL(*media_channel, GetStats(_))
1209 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001211
wu@webrtc.org97077a32013-10-25 21:18:33 +00001212 InitSessionStats(kVcName);
hbosdf6075a2016-12-19 04:58:02 -08001213 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1214 [this](const ChannelNamePairs&) {
1215 return std::unique_ptr<SessionStats>(
1216 new SessionStats(session_stats_));
1217 }));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001218
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001219 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001220 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221 stats.GetStats(NULL, &reports);
1222 std::string transport_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001223 StatsReport::kStatsReportTypeSsrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001224 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001225 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001226 ASSERT_NE(kNotFound, transport_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001227 // Transport id component ID will always be 1.
1228 // This has assumptions about how the ID is constructed. As is, this is
1229 // OK since this is for testing purposes only, but if we ever need this
1230 // in production, we should add a generic method that does this.
1231 size_t index = transport_id.find('-');
1232 ASSERT_NE(std::string::npos, index);
1233 std::string content = transport_id.substr(index + 1);
1234 index = content.rfind('-');
1235 ASSERT_NE(std::string::npos, index);
1236 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001237 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001238 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001239 const StatsReport* transport_report = FindReportById(reports, id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001240 ASSERT_FALSE(transport_report == NULL);
1241}
1242
wu@webrtc.org97077a32013-10-25 21:18:33 +00001243// This test verifies that a remote stats object will not be created for
1244// an outgoing SSRC where remote stats are not returned.
1245TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
deadbeefab9b2d12015-10-14 11:33:11 -07001246 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001247
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001248 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001249 // The transport_name known by the video channel.
wu@webrtc.org97077a32013-10-25 21:18:33 +00001250 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001251 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001252 worker_thread_, network_thread_, nullptr, media_channel, kVcName,
deadbeefac22f702017-01-12 21:59:29 -08001253 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001254 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001255 stats.AddStream(stream_);
1256
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001257 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001258 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001259 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001260 const StatsReport* remote_report = FindNthReportByType(reports,
1261 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001262 EXPECT_TRUE(remote_report == NULL);
1263}
1264
1265// This test verifies that a remote stats object will be created for
1266// an outgoing SSRC where stats are returned.
1267TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
deadbeefab9b2d12015-10-14 11:33:11 -07001268 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001269
deadbeefcbecd352015-09-23 11:50:27 -07001270 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1271 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001272 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1273 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001274
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001275 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001276 // The transport_name known by the video channel.
wu@webrtc.org97077a32013-10-25 21:18:33 +00001277 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001278 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001279 worker_thread_, network_thread_, nullptr, media_channel, kVcName,
deadbeefac22f702017-01-12 21:59:29 -08001280 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001281 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001282 stats.AddStream(stream_);
1283
wu@webrtc.org97077a32013-10-25 21:18:33 +00001284 // Instruct the session to return stats containing the transport channel.
1285 InitSessionStats(kVcName);
hbosdf6075a2016-12-19 04:58:02 -08001286 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1287 [this](const ChannelNamePairs&) {
1288 return std::unique_ptr<SessionStats>(
1289 new SessionStats(session_stats_));
1290 }));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001291
1292 // Constructs an ssrc stats update.
1293 cricket::VideoMediaInfo stats_read;
1294
1295 cricket::SsrcReceiverInfo remote_ssrc_stats;
1296 remote_ssrc_stats.timestamp = 12345.678;
1297 remote_ssrc_stats.ssrc = kSsrcOfTrack;
1298 cricket::VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001299 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001300 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
1301 stats_read.senders.push_back(video_sender_info);
1302
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001303 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1304 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001305 EXPECT_CALL(*media_channel, GetStats(_))
1306 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
wu@webrtc.org97077a32013-10-25 21:18:33 +00001307 Return(true)));
1308
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001309 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001310 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001311 stats.GetStats(NULL, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001312
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001313 const StatsReport* remote_report = FindNthReportByType(reports,
1314 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001315 EXPECT_FALSE(remote_report == NULL);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001316 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001317}
1318
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001319// This test verifies that the empty track report exists in the returned stats
1320// when StatsCollector::UpdateStats is called with ssrc stats.
1321TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
deadbeefab9b2d12015-10-14 11:33:11 -07001322 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001323
deadbeefcbecd352015-09-23 11:50:27 -07001324 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1325 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001326 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1327 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001328
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001329 const char kVideoChannelName[] = "video";
1330 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -08001331 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1332 [this](const ChannelNamePairs&) {
1333 return std::unique_ptr<SessionStats>(
1334 new SessionStats(session_stats_));
1335 }));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001336
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001337 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -08001338 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001339 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001340 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001341 AddIncomingVideoTrackStats();
1342 stats.AddStream(stream_);
1343
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001344 // Constructs an ssrc stats update.
1345 cricket::VideoReceiverInfo video_receiver_info;
1346 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001347 const int64_t kNumOfPacketsConcealed = 54321;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001348
1349 // Construct a stats value to read.
1350 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001351 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001352 stats_read.receivers.push_back(video_receiver_info);
1353
1354 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1355 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001356 EXPECT_CALL(*media_channel, GetStats(_))
1357 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001358 Return(true)));
1359
1360 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001361 StatsReports reports;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001362 stats.GetStats(NULL, &reports);
1363 // |reports| should contain at least one session report, one track report,
1364 // and one ssrc report.
1365 EXPECT_LE(static_cast<size_t>(3), reports.size());
1366 const StatsReport* track_report = FindNthReportByType(
1367 reports, StatsReport::kStatsReportTypeTrack, 1);
1368 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001369 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001370
1371 std::string ssrc_id = ExtractSsrcStatsValue(
1372 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001373 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001374
1375 std::string track_id = ExtractSsrcStatsValue(
1376 reports, StatsReport::kStatsValueNameTrackId);
1377 EXPECT_EQ(kRemoteTrackId, track_id);
1378}
1379
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001380// This test verifies the Ice Candidate report should contain the correct
1381// information from local/remote candidates.
1382TEST_F(StatsCollectorTest, IceCandidateReport) {
deadbeefab9b2d12015-10-14 11:33:11 -07001383 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001384
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001385 StatsReports reports; // returned values.
1386
1387 const int local_port = 2000;
1388 const char local_ip[] = "192.168.0.1";
1389 const int remote_port = 2001;
1390 const char remote_ip[] = "192.168.0.2";
1391
1392 rtc::SocketAddress local_address(local_ip, local_port);
1393 rtc::SocketAddress remote_address(remote_ip, remote_port);
1394 rtc::AdapterType network_type = rtc::ADAPTER_TYPE_ETHERNET;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001395 uint32_t priority = 1000;
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001396
1397 cricket::Candidate c;
nissec8ee8822017-01-18 07:20:55 -08001398 EXPECT_GT(c.id().length(), 0u);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001399 c.set_type(cricket::LOCAL_PORT_TYPE);
1400 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
1401 c.set_address(local_address);
1402 c.set_priority(priority);
1403 c.set_network_type(network_type);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001404 std::string report_id = AddCandidateReport(&stats, c, true)->id()->ToString();
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001405 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001406
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001407 c = cricket::Candidate();
nissec8ee8822017-01-18 07:20:55 -08001408 EXPECT_GT(c.id().length(), 0u);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001409 c.set_type(cricket::PRFLX_PORT_TYPE);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001410 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001411 c.set_address(remote_address);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001412 c.set_priority(priority);
1413 c.set_network_type(network_type);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001414 report_id = AddCandidateReport(&stats, c, false)->id()->ToString();
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001415 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001416
1417 stats.GetStats(NULL, &reports);
1418
1419 // Verify the local candidate report is populated correctly.
1420 EXPECT_EQ(
1421 local_ip,
1422 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1423 StatsReport::kStatsValueNameCandidateIPAddress));
1424 EXPECT_EQ(
1425 rtc::ToString<int>(local_port),
1426 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1427 StatsReport::kStatsValueNameCandidatePortNumber));
1428 EXPECT_EQ(
1429 cricket::UDP_PROTOCOL_NAME,
1430 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1431 StatsReport::kStatsValueNameCandidateTransportType));
1432 EXPECT_EQ(
1433 rtc::ToString<int>(priority),
1434 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1435 StatsReport::kStatsValueNameCandidatePriority));
1436 EXPECT_EQ(
1437 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1438 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1439 StatsReport::kStatsValueNameCandidateType));
1440 EXPECT_EQ(
1441 AdapterTypeToStatsType(network_type),
1442 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1443 StatsReport::kStatsValueNameCandidateNetworkType));
1444
1445 // Verify the remote candidate report is populated correctly.
1446 EXPECT_EQ(remote_ip,
1447 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1448 reports,
1449 StatsReport::kStatsValueNameCandidateIPAddress));
1450 EXPECT_EQ(rtc::ToString<int>(remote_port),
1451 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1452 reports,
1453 StatsReport::kStatsValueNameCandidatePortNumber));
1454 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1455 ExtractStatsValue(
1456 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1457 StatsReport::kStatsValueNameCandidateTransportType));
1458 EXPECT_EQ(rtc::ToString<int>(priority),
1459 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1460 reports,
1461 StatsReport::kStatsValueNameCandidatePriority));
1462 EXPECT_EQ(
1463 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1464 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1465 reports, StatsReport::kStatsValueNameCandidateType));
1466 EXPECT_EQ(kNotFound,
1467 ExtractStatsValue(
1468 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1469 StatsReport::kStatsValueNameCandidateNetworkType));
1470}
1471
wu@webrtc.org4551b792013-10-09 15:37:36 +00001472// This test verifies that all chained certificates are correctly
1473// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001474TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001475 // Build local certificate chain.
1476 std::vector<std::string> local_ders(5);
1477 local_ders[0] = "These";
1478 local_ders[1] = "are";
1479 local_ders[2] = "some";
1480 local_ders[3] = "der";
1481 local_ders[4] = "values";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001482 rtc::FakeSSLCertificate local_cert(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001483
1484 // Build remote certificate chain
1485 std::vector<std::string> remote_ders(4);
1486 remote_ders[0] = "A";
1487 remote_ders[1] = "non-";
1488 remote_ders[2] = "intersecting";
1489 remote_ders[3] = "set";
kwibergd1fe2812016-04-27 06:47:29 -07001490 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001491 new rtc::FakeSSLCertificate(DersToPems(remote_ders)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001492
kwibergb4d01c42016-04-06 05:15:06 -07001493 TestCertificateReports(local_cert, local_ders, std::move(remote_cert),
1494 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001495}
1496
1497// This test verifies that all certificates without chains are correctly
1498// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001499TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001500 // Build local certificate.
1501 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001502 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001503
1504 // Build remote certificate.
1505 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001506 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001507 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001508
1509 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001510 std::move(remote_cert),
1511 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001512}
1513
1514// This test verifies that the stats are generated correctly when no
1515// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001516TEST_F(StatsCollectorTest, NoTransport) {
deadbeefab9b2d12015-10-14 11:33:11 -07001517 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001518
deadbeefcbecd352015-09-23 11:50:27 -07001519 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1520 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001521 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1522 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001523
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001524 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001525
1526 // Fake stats to process.
1527 cricket::TransportChannelStats channel_stats;
1528 channel_stats.component = 1;
1529
1530 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001531 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +00001532 transport_stats.channel_stats.push_back(channel_stats);
1533
deadbeefd59daf82015-10-14 15:02:44 -07001534 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001535 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +00001536 transport_stats;
1537
1538 // Configure MockWebRtcSession
hbosdf6075a2016-12-19 04:58:02 -08001539 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1540 [&session_stats](const ChannelNamePairs&) {
1541 return std::unique_ptr<SessionStats>(
1542 new SessionStats(session_stats));
1543 }));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001544
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001545 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001546 stats.GetStats(NULL, &reports);
1547
1548 // Check that the local certificate is absent.
1549 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001550 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001551 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001552 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001553 ASSERT_EQ(kNotFound, local_certificate_id);
1554
1555 // Check that the remote certificate is absent.
1556 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001557 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001558 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001559 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001560 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001561
1562 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001563 std::string dtls_cipher_suite =
1564 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1565 StatsReport::kStatsValueNameDtlsCipher);
1566 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1567 std::string srtp_crypto_suite =
1568 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1569 StatsReport::kStatsValueNameSrtpCipher);
1570 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001571}
1572
1573// This test verifies that the stats are generated correctly when the transport
1574// does not have any certificates.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001575TEST_F(StatsCollectorTest, NoCertificates) {
deadbeefab9b2d12015-10-14 11:33:11 -07001576 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001577
deadbeefcbecd352015-09-23 11:50:27 -07001578 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1579 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001580 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1581 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001582
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001583 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001584
1585 // Fake stats to process.
1586 cricket::TransportChannelStats channel_stats;
1587 channel_stats.component = 1;
1588
1589 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001590 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +00001591 transport_stats.channel_stats.push_back(channel_stats);
1592
deadbeefd59daf82015-10-14 15:02:44 -07001593 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001594 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +00001595 transport_stats;
1596
wu@webrtc.org4551b792013-10-09 15:37:36 +00001597 // Configure MockWebRtcSession
hbosdf6075a2016-12-19 04:58:02 -08001598 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1599 [&session_stats](const ChannelNamePairs&) {
1600 return std::unique_ptr<SessionStats>(
1601 new SessionStats(session_stats));
1602 }));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001603 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001604 stats.GetStats(NULL, &reports);
1605
1606 // Check that the local certificate is absent.
1607 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001608 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001609 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001610 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001611 ASSERT_EQ(kNotFound, local_certificate_id);
1612
1613 // Check that the remote certificate is absent.
1614 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001615 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001616 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001617 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001618 ASSERT_EQ(kNotFound, remote_certificate_id);
1619}
1620
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001621// This test verifies that a remote certificate with an unsupported digest
1622// algorithm is correctly ignored.
1623TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1624 // Build a local certificate.
1625 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001626 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001627
1628 // Build a remote certificate with an unsupported digest algorithm.
1629 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001630 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001631 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
1632 remote_cert->set_digest_algorithm("foobar");
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001633
1634 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001635 std::move(remote_cert), std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001636}
1637
zhihuang6ba3b192016-05-13 11:46:35 -07001638// This test verifies that the audio/video related stats which are -1 initially
1639// will be filtered out.
1640TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) {
1641 StatsCollectorForTest stats(&pc_);
1642
1643 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1644 .WillRepeatedly(Return(false));
1645 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1646 .WillRepeatedly(Return(nullptr));
1647
1648 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1649 // The transport_name known by the voice channel.
1650 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001651 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001652 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001653 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
zhihuang6ba3b192016-05-13 11:46:35 -07001654
1655 // Create a local stream with a local audio track and adds it to the stats.
1656 if (stream_ == NULL)
1657 stream_ = webrtc::MediaStream::Create("streamlabel");
1658
1659 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1660 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1661 stream_->AddTrack(local_track);
1662 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
1663 .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
1664 stats.AddStream(stream_);
1665 stats.AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
1666
1667 // Create a remote stream with a remote audio track and adds it to the stats.
1668 rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
1669 webrtc::MediaStream::Create("remotestreamlabel"));
1670 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1671 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
1672 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
1673 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
1674 remote_stream->AddTrack(remote_track);
1675 stats.AddStream(remote_stream);
1676
1677 // Instruct the session to return stats containing the transport channel.
1678 InitSessionStats(kVcName);
hbosdf6075a2016-12-19 04:58:02 -08001679 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1680 [this](const ChannelNamePairs&) {
1681 return std::unique_ptr<SessionStats>(
1682 new SessionStats(session_stats_));
1683 }));
zhihuang6ba3b192016-05-13 11:46:35 -07001684
1685 cricket::VoiceSenderInfo voice_sender_info;
1686 voice_sender_info.add_ssrc(kSsrcOfTrack);
1687 // These values are set to -1 initially in audio_send_stream.
1688 // The voice_sender_info will read the values from audio_send_stream.
1689 voice_sender_info.rtt_ms = -1;
1690 voice_sender_info.packets_lost = -1;
1691 voice_sender_info.jitter_ms = -1;
1692
1693 // Some of the contents in |voice_sender_info| needs to be updated from the
1694 // |audio_track_|.
1695 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info);
1696
1697 cricket::VoiceReceiverInfo voice_receiver_info;
1698 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1699 voice_receiver_info.capture_start_ntp_time_ms = -1;
1700 voice_receiver_info.audio_level = -1;
1701
1702 // Constructs an ssrc stats update.
1703 cricket::VoiceMediaInfo stats_read;
1704 stats_read.senders.push_back(voice_sender_info);
1705 stats_read.receivers.push_back(voice_receiver_info);
1706
1707 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1708 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1709 EXPECT_CALL(*media_channel, GetStats(_))
1710 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read), Return(true)));
1711
1712 StatsReports reports;
1713 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1714
1715 // Get stats for the local track.
1716 stats.GetStats(local_track.get(), &reports);
1717 const StatsReport* report =
1718 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
1719 EXPECT_TRUE(report);
1720 // The -1 will not be added to the stats report.
1721 std::string value_in_report;
1722 EXPECT_FALSE(
1723 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1724 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1725 &value_in_report));
1726 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1727 &value_in_report));
1728 EXPECT_FALSE(GetValue(report,
1729 StatsReport::kStatsValueNameEchoCancellationQualityMin,
1730 &value_in_report));
1731 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1732 &value_in_report));
1733 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1734 &value_in_report));
1735
1736 // Get stats for the remote track.
1737 reports.clear();
1738 stats.GetStats(remote_track.get(), &reports);
1739 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
1740 EXPECT_TRUE(report);
1741 EXPECT_FALSE(GetValue(report,
1742 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1743 &value_in_report));
1744 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1745 &value_in_report));
1746}
1747
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001748// This test verifies that a local stats object can get statistics via
1749// AudioTrackInterface::GetStats() method.
1750TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
deadbeefab9b2d12015-10-14 11:33:11 -07001751 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001752
deadbeefcbecd352015-09-23 11:50:27 -07001753 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1754 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001755 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1756 .WillRepeatedly(Return(nullptr));
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001757
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001758 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001759 // The transport_name known by the voice channel.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001760 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001761 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001762 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001763 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001764 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001765 stats.AddStream(stream_);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001766 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001767
1768 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001769 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001770
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001771 cricket::VoiceMediaInfo stats_read;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001772 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001773 SetupAndVerifyAudioTrackStats(
1774 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1775 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001776
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001777 // Verify that there is no remote report for the local audio track because
1778 // we did not set it up.
1779 const StatsReport* remote_report = FindNthReportByType(reports,
1780 StatsReport::kStatsReportTypeRemoteSsrc, 1);
1781 EXPECT_TRUE(remote_report == NULL);
1782}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001783
1784// This test verifies that audio receive streams populate stats reports
1785// correctly.
1786TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07001787 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001788
deadbeefcbecd352015-09-23 11:50:27 -07001789 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1790 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001791 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1792 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001793
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001794 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001795 // The transport_name known by the voice channel.
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001796 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001797 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001798 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001799 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001800 AddIncomingAudioTrackStats();
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001801 stats.AddStream(stream_);
1802
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001803 cricket::VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001804 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001805 voice_receiver_info.codec_name = "fake_codec";
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001806
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001807 cricket::VoiceMediaInfo stats_read;
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001808 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001809 SetupAndVerifyAudioTrackStats(
1810 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1811 media_channel, NULL, &voice_receiver_info, &stats_read, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001812}
1813
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001814// This test verifies that a local stats object won't update its statistics
1815// after a RemoveLocalAudioTrack() call.
1816TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07001817 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001818
deadbeefcbecd352015-09-23 11:50:27 -07001819 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1820 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001821 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1822 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001823
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001824 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001825 // The transport_name known by the voice channel.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001826 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001827 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001828 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001829 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001830 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001831 stats.AddStream(stream_);
1832 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1833
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001834 // Instruct the session to return stats containing the transport channel.
1835 InitSessionStats(kVcName);
hbosdf6075a2016-12-19 04:58:02 -08001836 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1837 [this](const ChannelNamePairs&) {
1838 return std::unique_ptr<SessionStats>(
1839 new SessionStats(session_stats_));
1840 }));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001841
1842 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1843 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001844 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001845
1846 // Constructs an ssrc stats update.
1847 cricket::VoiceMediaInfo stats_read;
1848 stats_read.senders.push_back(voice_sender_info);
1849
1850 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1851 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1852 EXPECT_CALL(*media_channel, GetStats(_))
1853 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1854 Return(true)));
1855
1856 StatsReports reports; // returned values.
1857 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1858 stats.GetStats(NULL, &reports);
1859
1860 // The report will exist since we don't remove them in RemoveStream().
1861 const StatsReport* report = FindNthReportByType(
1862 reports, StatsReport::kStatsReportTypeSsrc, 1);
1863 EXPECT_FALSE(report == NULL);
jbauchbe24c942015-06-22 15:06:43 -07001864 EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001865 std::string track_id = ExtractSsrcStatsValue(
1866 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001867 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001868 std::string ssrc_id = ExtractSsrcStatsValue(
1869 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001870 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001871
1872 // Verifies the values in the track report, no value will be changed by the
1873 // AudioTrackInterface::GetSignalValue() and
1874 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1875 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1876}
1877
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001878// This test verifies that when ongoing and incoming audio tracks are using
1879// the same ssrc, they populate stats reports correctly.
1880TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
deadbeefab9b2d12015-10-14 11:33:11 -07001881 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001882
deadbeefcbecd352015-09-23 11:50:27 -07001883 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1884 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001885 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1886 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001887
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001888 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001889 // The transport_name known by the voice channel.
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001890 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001891 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001892 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001893 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001894
1895 // Create a local stream with a local audio track and adds it to the stats.
1896 AddOutgoingAudioTrackStats();
1897 stats.AddStream(stream_);
1898 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1899
1900 // Create a remote stream with a remote audio track and adds it to the stats.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001901 rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001902 webrtc::MediaStream::Create("remotestreamlabel"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001903 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1904 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001905 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +00001906 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001907 remote_stream->AddTrack(remote_track);
1908 stats.AddStream(remote_stream);
1909
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001910 // Instruct the session to return stats containing the transport channel.
1911 InitSessionStats(kVcName);
hbosdf6075a2016-12-19 04:58:02 -08001912 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
1913 [this](const ChannelNamePairs&) {
1914 return std::unique_ptr<SessionStats>(
1915 new SessionStats(session_stats_));
1916 }));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001917
1918 cricket::VoiceSenderInfo voice_sender_info;
1919 InitVoiceSenderInfo(&voice_sender_info);
1920
1921 // Some of the contents in |voice_sender_info| needs to be updated from the
1922 // |audio_track_|.
1923 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info);
1924
1925 cricket::VoiceReceiverInfo voice_receiver_info;
1926 InitVoiceReceiverInfo(&voice_receiver_info);
1927
1928 // Constructs an ssrc stats update.
1929 cricket::VoiceMediaInfo stats_read;
1930 stats_read.senders.push_back(voice_sender_info);
1931 stats_read.receivers.push_back(voice_receiver_info);
1932
1933 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1934 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1935 EXPECT_CALL(*media_channel, GetStats(_))
1936 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1937 Return(true)));
1938
1939 StatsReports reports; // returned values.
1940 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1941
1942 // Get stats for the local track.
1943 stats.GetStats(audio_track_.get(), &reports);
1944 const StatsReport* track_report = FindNthReportByType(
1945 reports, StatsReport::kStatsReportTypeSsrc, 1);
1946 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001947 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001948 std::string track_id = ExtractSsrcStatsValue(
1949 reports, StatsReport::kStatsValueNameTrackId);
1950 EXPECT_EQ(kLocalTrackId, track_id);
1951 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1952
1953 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001954 reports.clear();
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001955 stats.GetStats(remote_track.get(), &reports);
1956 track_report = FindNthReportByType(reports,
1957 StatsReport::kStatsReportTypeSsrc, 1);
1958 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001959 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001960 track_id = ExtractSsrcStatsValue(reports,
1961 StatsReport::kStatsValueNameTrackId);
1962 EXPECT_EQ(kRemoteTrackId, track_id);
1963 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1964}
1965
xians@webrtc.org01bda202014-07-09 07:38:38 +00001966// This test verifies that when two outgoing audio tracks are using the same
1967// ssrc at different times, they populate stats reports correctly.
1968// TODO(xians): Figure out if it is possible to encapsulate the setup and
1969// avoid duplication of code in test cases.
1970TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) {
deadbeefab9b2d12015-10-14 11:33:11 -07001971 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001972
deadbeefcbecd352015-09-23 11:50:27 -07001973 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1974 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001975 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1976 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001977
xians@webrtc.org01bda202014-07-09 07:38:38 +00001978 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001979 // The transport_name known by the voice channel.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001980 const std::string kVcName("vcname");
deadbeef7af91dd2016-12-13 11:29:11 -08001981 cricket::VoiceChannel voice_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08001982 worker_thread_, network_thread_, nullptr, media_engine_, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08001983 kVcName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001984
1985 // Create a local stream with a local audio track and adds it to the stats.
1986 AddOutgoingAudioTrackStats();
1987 stats.AddStream(stream_);
1988 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
1989
1990 cricket::VoiceSenderInfo voice_sender_info;
1991 voice_sender_info.add_ssrc(kSsrcOfTrack);
1992
1993 cricket::VoiceMediaInfo stats_read;
1994 StatsReports reports; // returned values.
1995 SetupAndVerifyAudioTrackStats(
1996 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1997 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
1998
1999 // Remove the previous audio track from the stream.
2000 stream_->RemoveTrack(audio_track_.get());
2001 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
2002
2003 // Create a new audio track and adds it to the stream and stats.
2004 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002005 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
2006 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
xians@webrtc.org01bda202014-07-09 07:38:38 +00002007 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
2008 .WillOnce(DoAll(SetArgPointee<1>(kNewTrackId), Return(true)));
2009 stream_->AddTrack(new_audio_track);
2010
2011 stats.AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +00002012 stats.ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +00002013 cricket::VoiceSenderInfo new_voice_sender_info;
2014 InitVoiceSenderInfo(&new_voice_sender_info);
2015 cricket::VoiceMediaInfo new_stats_read;
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00002016 reports.clear();
xians@webrtc.org01bda202014-07-09 07:38:38 +00002017 SetupAndVerifyAudioTrackStats(
2018 new_audio_track.get(), stream_.get(), &stats, &voice_channel, kVcName,
2019 media_channel, &new_voice_sender_info, NULL, &new_stats_read, &reports);
2020}
2021
sakal43536c32016-10-24 01:46:43 -07002022// This test verifies that stats are correctly set in video send ssrc stats.
2023TEST_F(StatsCollectorTest, VerifyVideoSendSsrcStats) {
2024 StatsCollectorForTest stats(&pc_);
2025
2026 EXPECT_CALL(session_, GetLocalCertificate(_, _))
2027 .WillRepeatedly(Return(false));
2028 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
2029 .WillRepeatedly(Return(nullptr));
2030
2031 const char kVideoChannelName[] = "video";
2032
2033 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -08002034 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
2035 [this](const ChannelNamePairs&) {
2036 return std::unique_ptr<SessionStats>(
2037 new SessionStats(session_stats_));
2038 }));
sakal43536c32016-10-24 01:46:43 -07002039
2040 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -08002041 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08002042 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08002043 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
sakal43536c32016-10-24 01:46:43 -07002044 StatsReports reports; // returned values.
2045 cricket::VideoSenderInfo video_sender_info;
2046 cricket::VideoMediaInfo stats_read;
2047
2048 AddOutgoingVideoTrackStats();
2049 stats.AddStream(stream_);
2050
2051 // Construct a stats value to read.
2052 video_sender_info.add_ssrc(1234);
2053 video_sender_info.frames_encoded = 10;
sakal87da4042016-10-31 06:53:47 -07002054 video_sender_info.qp_sum = rtc::Optional<uint64_t>(11);
sakal43536c32016-10-24 01:46:43 -07002055 stats_read.senders.push_back(video_sender_info);
2056
2057 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
2058 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
2059 EXPECT_CALL(*media_channel, GetStats(_))
2060 .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
2061 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
2062 stats.GetStats(NULL, &reports);
2063 EXPECT_EQ(rtc::ToString(video_sender_info.frames_encoded),
2064 ExtractSsrcStatsValue(reports,
2065 StatsReport::kStatsValueNameFramesEncoded));
sakal87da4042016-10-31 06:53:47 -07002066 EXPECT_EQ(rtc::ToString(*video_sender_info.qp_sum),
2067 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakal43536c32016-10-24 01:46:43 -07002068}
2069
sakale5ba44e2016-10-26 07:09:24 -07002070// This test verifies that stats are correctly set in video receive ssrc stats.
2071TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) {
2072 StatsCollectorForTest stats(&pc_);
2073
2074 EXPECT_CALL(session_, GetLocalCertificate(_, _))
2075 .WillRepeatedly(Return(false));
2076 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
2077 .WillRepeatedly(Return(nullptr));
2078
2079 const char kVideoChannelName[] = "video";
2080
2081 InitSessionStats(kVideoChannelName);
hbosdf6075a2016-12-19 04:58:02 -08002082 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Invoke(
2083 [this](const ChannelNamePairs&) {
2084 return std::unique_ptr<SessionStats>(
2085 new SessionStats(session_stats_));
2086 }));
sakale5ba44e2016-10-26 07:09:24 -07002087
2088 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeef7af91dd2016-12-13 11:29:11 -08002089 cricket::VideoChannel video_channel(
zhihuangf5b251b2017-01-12 19:37:48 -08002090 worker_thread_, network_thread_, nullptr, media_channel,
deadbeefac22f702017-01-12 21:59:29 -08002091 kVideoChannelName, kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
sakale5ba44e2016-10-26 07:09:24 -07002092 StatsReports reports; // returned values.
2093 cricket::VideoReceiverInfo video_receiver_info;
2094 cricket::VideoMediaInfo stats_read;
2095
2096 AddIncomingVideoTrackStats();
2097 stats.AddStream(stream_);
2098
2099 // Construct a stats value to read.
2100 video_receiver_info.add_ssrc(1234);
2101 video_receiver_info.frames_decoded = 10;
sakalcc452e12017-02-09 04:53:45 -08002102 video_receiver_info.qp_sum = rtc::Optional<uint64_t>(11);
sakale5ba44e2016-10-26 07:09:24 -07002103 stats_read.receivers.push_back(video_receiver_info);
2104
2105 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
2106 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
2107 EXPECT_CALL(*media_channel, GetStats(_))
2108 .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
2109 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
2110 stats.GetStats(NULL, &reports);
2111 EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded),
2112 ExtractSsrcStatsValue(reports,
2113 StatsReport::kStatsValueNameFramesDecoded));
sakalcc452e12017-02-09 04:53:45 -08002114 EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum),
2115 ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum));
sakale5ba44e2016-10-26 07:09:24 -07002116}
2117
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00002118} // namespace webrtc