blob: e0657a1b95cb7c47b1aa6ac1d791ce9feaf787ae [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
Henrik Kjellander15583c12016-02-10 10:53:12 +010016#include "webrtc/api/statscollector.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
xians@webrtc.org4cb01282014-06-12 14:57:05 +000018#include "testing/gmock/include/gmock/gmock.h"
19#include "testing/gtest/include/gtest/gtest.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010020#include "webrtc/api/mediastream.h"
21#include "webrtc/api/mediastreaminterface.h"
22#include "webrtc/api/mediastreamtrack.h"
23#include "webrtc/api/peerconnection.h"
24#include "webrtc/api/peerconnectionfactory.h"
25#include "webrtc/api/test/fakedatachannelprovider.h"
nisseaf510af2016-03-21 08:20:42 -070026#include "webrtc/api/test/fakevideotracksource.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010027#include "webrtc/api/videotrack.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000028#include "webrtc/base/base64.h"
29#include "webrtc/base/fakesslidentity.h"
30#include "webrtc/base/gunit.h"
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000031#include "webrtc/base/network.h"
kjellandera96e2d72016-02-04 23:52:28 -080032#include "webrtc/media/base/fakemediaengine.h"
deadbeefcbecd352015-09-23 11:50:27 -070033#include "webrtc/p2p/base/faketransportcontroller.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010034#include "webrtc/pc/channelmanager.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
36using testing::_;
37using testing::DoAll;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000038using testing::Field;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039using testing::Return;
40using testing::ReturnNull;
deadbeefab9b2d12015-10-14 11:33:11 -070041using testing::ReturnRef;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042using testing::SetArgPointee;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000043using webrtc::PeerConnectionInterface;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000044using webrtc::StatsReport;
45using webrtc::StatsReports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046
47namespace cricket {
48
49class ChannelManager;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050
51} // namespace cricket
52
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000053namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
tkchin7d06a8c2016-04-04 14:10:43 -070055namespace internal {
56// This value comes from openssl/tls1.h
57static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
58} // namespace internal
59
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060// Error return values
61const char kNotFound[] = "NOT FOUND";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062
wu@webrtc.org97077a32013-10-25 21:18:33 +000063// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000064const char kLocalTrackId[] = "local_track_id";
65const char kRemoteTrackId[] = "remote_track_id";
Peter Boström0c4e06b2015-10-07 12:23:21 +020066const uint32_t kSsrcOfTrack = 1234;
wu@webrtc.org97077a32013-10-25 21:18:33 +000067
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068class MockWebRtcSession : public webrtc::WebRtcSession {
69 public:
nisseef8b61e2016-04-29 06:09:15 -070070 // TODO(nisse): Valid overrides commented out, because the gmock
71 // methods don't use any override declarations, and we want to avoid
72 // warnings from -Winconsistent-missing-override. See
73 // http://crbug.com/428099.
stefanc1aeaf02015-10-15 07:26:07 -070074 explicit MockWebRtcSession(webrtc::MediaControllerInterface* media_controller)
zhihuang29ff8442016-07-27 11:07:25 -070075 : WebRtcSession(
76 media_controller,
77 rtc::Thread::Current(),
78 rtc::Thread::Current(),
79 rtc::Thread::Current(),
80 nullptr,
81 std::unique_ptr<cricket::TransportController>(
82 new cricket::TransportController(rtc::Thread::Current(),
83 rtc::Thread::Current(),
84 nullptr))) {}
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000085 MOCK_METHOD0(voice_channel, cricket::VoiceChannel*());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 MOCK_METHOD0(video_channel, cricket::VideoChannel*());
xians@webrtc.org4cb01282014-06-12 14:57:05 +000087 // Libjingle uses "local" for a outgoing track, and "remote" for a incoming
88 // track.
Peter Boström0c4e06b2015-10-07 12:23:21 +020089 MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32_t, std::string*));
90 MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32_t, std::string*));
deadbeefd59daf82015-10-14 15:02:44 -070091 MOCK_METHOD1(GetTransportStats, bool(SessionStats*));
deadbeefcbecd352015-09-23 11:50:27 -070092 MOCK_METHOD2(GetLocalCertificate,
93 bool(const std::string& transport_name,
94 rtc::scoped_refptr<rtc::RTCCertificate>* certificate));
kwibergb4d01c42016-04-06 05:15:06 -070095
96 // Workaround for gmock's inability to cope with move-only return values.
jbauch555604a2016-04-26 03:13:22 -070097 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(
nisseef8b61e2016-04-29 06:09:15 -070098 const std::string& transport_name) /* override */ {
jbauch555604a2016-04-26 03:13:22 -070099 return std::unique_ptr<rtc::SSLCertificate>(
kwibergb4d01c42016-04-06 05:15:06 -0700100 GetRemoteSSLCertificate_ReturnsRawPointer(transport_name));
101 }
102 MOCK_METHOD1(GetRemoteSSLCertificate_ReturnsRawPointer,
103 rtc::SSLCertificate*(const std::string& transport_name));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104};
105
deadbeefab9b2d12015-10-14 11:33:11 -0700106// The factory isn't really used; it just satisfies the base PeerConnection.
107class FakePeerConnectionFactory
108 : public rtc::RefCountedObject<PeerConnectionFactory> {};
109
110class MockPeerConnection
111 : public rtc::RefCountedObject<webrtc::PeerConnection> {
112 public:
113 MockPeerConnection()
114 : rtc::RefCountedObject<webrtc::PeerConnection>(
115 new FakePeerConnectionFactory()) {}
116 MOCK_METHOD0(session, WebRtcSession*());
117 MOCK_CONST_METHOD0(sctp_data_channels,
118 const std::vector<rtc::scoped_refptr<DataChannel>>&());
119};
120
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
122 public:
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200123 MockVideoMediaChannel() :
124 cricket::FakeVideoMediaChannel(NULL, cricket::VideoOptions()) {}
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000125 MOCK_METHOD1(GetStats, bool(cricket::VideoMediaInfo*));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126};
127
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000128class MockVoiceMediaChannel : public cricket::FakeVoiceMediaChannel {
129 public:
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200130 MockVoiceMediaChannel() :
131 cricket::FakeVoiceMediaChannel(NULL, cricket::AudioOptions()) {}
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000132 MOCK_METHOD1(GetStats, bool(cricket::VoiceMediaInfo*));
133};
134
135class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
136 public:
137 FakeAudioProcessor() {}
138 ~FakeAudioProcessor() {}
139
140 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000141 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000142 stats->typing_noise_detected = true;
143 stats->echo_return_loss = 2;
144 stats->echo_return_loss_enhancement = 3;
145 stats->echo_delay_median_ms = 4;
146 stats->aec_quality_min = 5.1f;
147 stats->echo_delay_std_ms = 6;
148 }
149};
150
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000151class FakeAudioTrack
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000152 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
153 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000154 explicit FakeAudioTrack(const std::string& id)
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000155 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000156 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000157 std::string kind() const override { return "audio"; }
158 webrtc::AudioSourceInterface* GetSource() const override { return NULL; }
159 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
160 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
161 bool GetSignalLevel(int* level) override {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000162 *level = 1;
163 return true;
164 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000165 rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
166 override {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000167 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000168 }
169
170 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000172};
173
zhihuang6ba3b192016-05-13 11:46:35 -0700174// This fake audio processor is used to verify that the undesired initial values
175// (-1) will be filtered out.
176class FakeAudioProcessorWithInitValue : public webrtc::AudioProcessorInterface {
177 public:
178 FakeAudioProcessorWithInitValue() {}
179 ~FakeAudioProcessorWithInitValue() {}
180
181 private:
182 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
183 stats->typing_noise_detected = false;
184 stats->echo_return_loss = -100;
185 stats->echo_return_loss_enhancement = -100;
186 stats->echo_delay_median_ms = -1;
187 stats->aec_quality_min = -1.0f;
188 stats->echo_delay_std_ms = -1;
189 }
190};
191
192class FakeAudioTrackWithInitValue
193 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
194 public:
195 explicit FakeAudioTrackWithInitValue(const std::string& id)
196 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
197 processor_(
198 new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {}
199 std::string kind() const override { return "audio"; }
200 webrtc::AudioSourceInterface* GetSource() const override { return NULL; }
201 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
202 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
203 bool GetSignalLevel(int* level) override {
204 *level = 1;
205 return true;
206 }
207 rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
208 override {
209 return processor_;
210 }
211
212 private:
213 rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_;
214};
215
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000216bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000217 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000218 std::string* value) {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000219 const StatsReport::Value* v = report->FindValue(name);
220 if (!v)
221 return false;
222 *value = v->ToString();
223 return true;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000224}
225
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000226std::string ExtractStatsValue(const StatsReport::StatsType& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000227 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000228 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000229 for (const auto* r : reports) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000230 std::string ret;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000231 if (r->type() == type && GetValue(r, name, &ret))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000232 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 }
234
235 return kNotFound;
236}
237
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000238StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
239 const std::string& value) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000240 EXPECT_FALSE(value.empty());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000241 StatsReport::Id id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000242 if (value.empty())
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000243 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000244
245 // This has assumptions about how the ID is constructed. As is, this is
246 // OK since this is for testing purposes only, but if we ever need this
247 // in production, we should add a generic method that does this.
248 size_t index = value.find('_');
249 EXPECT_NE(index, std::string::npos);
250 if (index == std::string::npos || index == (value.length() - 1))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000251 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000252
253 id = StatsReport::NewTypedId(type, value.substr(index + 1));
254 EXPECT_EQ(id->ToString(), value);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000255 return id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000256}
257
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000258StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
259 return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000260}
261
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262// Finds the |n|-th report of type |type| in |reports|.
263// |n| starts from 1 for finding the first report.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000264const StatsReport* FindNthReportByType(
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000265 const StatsReports& reports, const StatsReport::StatsType& type, int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000267 if (reports[i]->type() == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 n--;
269 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000270 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 }
272 }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000273 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274}
275
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000276const StatsReport* FindReportById(const StatsReports& reports,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000277 const StatsReport::Id& id) {
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000278 for (const auto* r : reports) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000279 if (r->id()->Equals(id))
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000280 return r;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 }
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000282 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000283}
284
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000285std::string ExtractSsrcStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000286 StatsReport::StatsValueName name) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000287 return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288}
289
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000290std::string ExtractBweStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000291 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000292 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000293 StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294}
295
wu@webrtc.org4551b792013-10-09 15:37:36 +0000296std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000297 return rtc::SSLIdentity::DerToPem(
298 rtc::kPemTypeCertificate,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000299 reinterpret_cast<const unsigned char*>(der.c_str()),
300 der.length());
301}
302
303std::vector<std::string> DersToPems(
304 const std::vector<std::string>& ders) {
305 std::vector<std::string> pems(ders.size());
306 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
307 return pems;
308}
309
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000310void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000311 const std::vector<std::string>& ders,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000312 const StatsReport::Id& start_id) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000313 StatsReport::Id cert_id;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000314 const StatsReport::Id* certificate_id = &start_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000315 size_t i = 0;
316 while (true) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000317 const StatsReport* report = FindReportById(reports, *certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000318 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000319
wu@webrtc.org4551b792013-10-09 15:37:36 +0000320 std::string der_base64;
321 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000322 report, StatsReport::kStatsValueNameDer, &der_base64));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000323 std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000324 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000325
326 std::string fingerprint_algorithm;
327 EXPECT_TRUE(GetValue(
328 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000329 StatsReport::kStatsValueNameFingerprintAlgorithm,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000330 &fingerprint_algorithm));
331 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000332 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000333 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
334
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000335 std::string fingerprint;
336 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
337 &fingerprint));
338 EXPECT_FALSE(fingerprint.empty());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000339
wu@webrtc.org4551b792013-10-09 15:37:36 +0000340 ++i;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000341 std::string issuer_id;
342 if (!GetValue(report, StatsReport::kStatsValueNameIssuerId,
343 &issuer_id)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000344 break;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000345 }
346
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000347 cert_id = IdFromCertIdString(issuer_id);
348 certificate_id = &cert_id;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000349 }
350 EXPECT_EQ(ders.size(), i);
351}
352
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000353void VerifyVoiceReceiverInfoReport(
354 const StatsReport* report,
355 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000356 std::string value_in_report;
357 EXPECT_TRUE(GetValue(
358 report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000359 EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000360 EXPECT_TRUE(GetValue(
361 report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200362 EXPECT_EQ(rtc::ToString<int64_t>(info.bytes_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000363 EXPECT_TRUE(GetValue(
364 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000365 EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000366 EXPECT_TRUE(GetValue(
367 report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000368 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000369 EXPECT_TRUE(GetValue(
370 report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
371 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000372 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000373 value_in_report);
374 EXPECT_TRUE(GetValue(
375 report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000376 EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000377 EXPECT_TRUE(GetValue(
378 report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000379 EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000380 EXPECT_TRUE(GetValue(
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000381 report, StatsReport::kStatsValueNameSpeechExpandRate, &value_in_report));
382 EXPECT_EQ(rtc::ToString<float>(info.speech_expand_rate), value_in_report);
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200383 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
384 &value_in_report));
385 EXPECT_EQ(rtc::ToString<float>(info.accelerate_rate), value_in_report);
386 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
387 &value_in_report));
388 EXPECT_EQ(rtc::ToString<float>(info.preemptive_expand_rate), value_in_report);
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000389 EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
390 &value_in_report));
391 EXPECT_EQ(rtc::ToString<float>(info.secondary_decoded_rate), value_in_report);
392 EXPECT_TRUE(GetValue(
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000393 report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000394 EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000395 EXPECT_TRUE(GetValue(
396 report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000397 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000398 value_in_report);
399 EXPECT_TRUE(GetValue(
400 report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000401 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000402 value_in_report);
403 EXPECT_TRUE(GetValue(
404 report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000405 EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000406 EXPECT_TRUE(GetValue(
407 report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000408 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000409 EXPECT_TRUE(GetValue(
410 report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000411 EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000412 EXPECT_TRUE(GetValue(
413 report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000414 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +0000415 EXPECT_TRUE(GetValue(
416 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000417}
418
419
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000420void VerifyVoiceSenderInfoReport(const StatsReport* report,
421 const cricket::VoiceSenderInfo& sinfo) {
422 std::string value_in_report;
423 EXPECT_TRUE(GetValue(
424 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
425 EXPECT_EQ(sinfo.codec_name, value_in_report);
426 EXPECT_TRUE(GetValue(
427 report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200428 EXPECT_EQ(rtc::ToString<int64_t>(sinfo.bytes_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000429 EXPECT_TRUE(GetValue(
430 report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000431 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000432 EXPECT_TRUE(GetValue(
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000433 report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000434 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000435 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000436 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000437 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000438 EXPECT_TRUE(GetValue(
439 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000440 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000441 EXPECT_TRUE(GetValue(
442 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000443 EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000444 EXPECT_TRUE(GetValue(
445 report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
446 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000447 EXPECT_EQ(rtc::ToString<float>(sinfo.aec_quality_min), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000448 EXPECT_TRUE(GetValue(
449 report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000450 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_median_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000451 value_in_report);
452 EXPECT_TRUE(GetValue(
453 report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000454 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_std_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000455 value_in_report);
456 EXPECT_TRUE(GetValue(
457 report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000458 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000459 value_in_report);
460 EXPECT_TRUE(GetValue(
461 report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
462 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000463 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss_enhancement),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000464 value_in_report);
465 EXPECT_TRUE(GetValue(
466 report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000467 EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000468 EXPECT_TRUE(GetValue(
469 report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
470 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
471 EXPECT_EQ(typing_detected, value_in_report);
472}
473
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000474// Helper methods to avoid duplication of code.
475void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
476 voice_sender_info->add_ssrc(kSsrcOfTrack);
477 voice_sender_info->codec_name = "fake_codec";
478 voice_sender_info->bytes_sent = 100;
479 voice_sender_info->packets_sent = 101;
480 voice_sender_info->rtt_ms = 102;
481 voice_sender_info->fraction_lost = 103;
482 voice_sender_info->jitter_ms = 104;
483 voice_sender_info->packets_lost = 105;
484 voice_sender_info->ext_seqnum = 106;
485 voice_sender_info->audio_level = 107;
486 voice_sender_info->echo_return_loss = 108;
487 voice_sender_info->echo_return_loss_enhancement = 109;
488 voice_sender_info->echo_delay_median_ms = 110;
489 voice_sender_info->echo_delay_std_ms = 111;
490 voice_sender_info->aec_quality_min = 112.0f;
491 voice_sender_info->typing_noise_detected = false;
492}
493
494void UpdateVoiceSenderInfoFromAudioTrack(
zhihuang6ba3b192016-05-13 11:46:35 -0700495 AudioTrackInterface* audio_track,
496 cricket::VoiceSenderInfo* voice_sender_info) {
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000497 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
498 webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
499 audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats);
500 voice_sender_info->typing_noise_detected =
501 audio_processor_stats.typing_noise_detected;
502 voice_sender_info->echo_return_loss = audio_processor_stats.echo_return_loss;
503 voice_sender_info->echo_return_loss_enhancement =
504 audio_processor_stats.echo_return_loss_enhancement;
505 voice_sender_info->echo_delay_median_ms =
506 audio_processor_stats.echo_delay_median_ms;
507 voice_sender_info->aec_quality_min = audio_processor_stats.aec_quality_min;
508 voice_sender_info->echo_delay_std_ms =
509 audio_processor_stats.echo_delay_std_ms;
510}
511
512void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
513 voice_receiver_info->add_ssrc(kSsrcOfTrack);
514 voice_receiver_info->bytes_rcvd = 110;
515 voice_receiver_info->packets_rcvd = 111;
516 voice_receiver_info->packets_lost = 112;
517 voice_receiver_info->fraction_lost = 113;
518 voice_receiver_info->packets_lost = 114;
519 voice_receiver_info->ext_seqnum = 115;
520 voice_receiver_info->jitter_ms = 116;
521 voice_receiver_info->jitter_buffer_ms = 117;
522 voice_receiver_info->jitter_buffer_preferred_ms = 118;
523 voice_receiver_info->delay_estimate_ms = 119;
524 voice_receiver_info->audio_level = 120;
525 voice_receiver_info->expand_rate = 121;
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000526 voice_receiver_info->speech_expand_rate = 122;
527 voice_receiver_info->secondary_decoded_rate = 123;
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200528 voice_receiver_info->accelerate_rate = 124;
529 voice_receiver_info->preemptive_expand_rate = 125;
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000530}
531
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000532class StatsCollectorForTest : public webrtc::StatsCollector {
533 public:
deadbeefab9b2d12015-10-14 11:33:11 -0700534 explicit StatsCollectorForTest(PeerConnection* pc)
535 : StatsCollector(pc), time_now_(19477) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000536
537 double GetTimeNow() override {
538 return time_now_;
539 }
540
541 private:
542 double time_now_;
543};
544
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000545class StatsCollectorTest : public testing::Test {
546 protected:
547 StatsCollectorTest()
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200548 : worker_thread_(rtc::Thread::Current()),
549 network_thread_(rtc::Thread::Current()),
550 media_engine_(new cricket::FakeMediaEngine()),
551 channel_manager_(new cricket::ChannelManager(media_engine_,
552 worker_thread_,
553 network_thread_)),
stefanc1aeaf02015-10-15 07:26:07 -0700554 media_controller_(
nisse51542be2016-02-12 02:27:06 -0800555 webrtc::MediaControllerInterface::Create(cricket::MediaConfig(),
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200556 worker_thread_,
stefanc1aeaf02015-10-15 07:26:07 -0700557 channel_manager_.get())),
558 session_(media_controller_.get()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000559 // By default, we ignore session GetStats calls.
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +0000560 EXPECT_CALL(session_, GetTransportStats(_)).WillRepeatedly(Return(false));
deadbeefab9b2d12015-10-14 11:33:11 -0700561 // Add default returns for mock classes.
562 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
563 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
564 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
565 EXPECT_CALL(pc_, sctp_data_channels())
566 .WillRepeatedly(ReturnRef(data_channels_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 }
568
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000569 ~StatsCollectorTest() {}
570
wu@webrtc.org97077a32013-10-25 21:18:33 +0000571 // This creates a standard setup with a transport called "trspname"
572 // having one transport channel
573 // and the specified virtual connection name.
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000574 void InitSessionStats(const std::string& vc_name) {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000575 const std::string kTransportName("trspname");
576 cricket::TransportStats transport_stats;
577 cricket::TransportChannelStats channel_stats;
578 channel_stats.component = 1;
deadbeefcbecd352015-09-23 11:50:27 -0700579 transport_stats.transport_name = kTransportName;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000580 transport_stats.channel_stats.push_back(channel_stats);
581
582 session_stats_.transport_stats[kTransportName] = transport_stats;
583 session_stats_.proxy_to_transport[vc_name] = kTransportName;
584 }
585
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000586 // Adds a outgoing video track with a given SSRC into the stats.
587 void AddOutgoingVideoTrackStats() {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000588 stream_ = webrtc::MediaStream::Create("streamlabel");
nisseaf510af2016-03-21 08:20:42 -0700589 track_ = webrtc::VideoTrack::Create(kLocalTrackId,
590 webrtc::FakeVideoTrackSource::Create());
wu@webrtc.org97077a32013-10-25 21:18:33 +0000591 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000592 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
593 .WillRepeatedly(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000594 }
595
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000596 // Adds a incoming video track with a given SSRC into the stats.
597 void AddIncomingVideoTrackStats() {
598 stream_ = webrtc::MediaStream::Create("streamlabel");
nisseaf510af2016-03-21 08:20:42 -0700599 track_ = webrtc::VideoTrack::Create(kRemoteTrackId,
600 webrtc::FakeVideoTrackSource::Create());
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000601 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000602 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000603 .WillRepeatedly(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000604 }
605
606 // Adds a outgoing audio track with a given SSRC into the stats.
607 void AddOutgoingAudioTrackStats() {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000608 if (stream_ == NULL)
609 stream_ = webrtc::MediaStream::Create("streamlabel");
610
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000611 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000612 kLocalTrackId);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000613 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000614 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000615 .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000616 }
617
618 // Adds a incoming audio track with a given SSRC into the stats.
619 void AddIncomingAudioTrackStats() {
620 if (stream_ == NULL)
621 stream_ = webrtc::MediaStream::Create("streamlabel");
622
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000623 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000624 kRemoteTrackId);
625 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000626 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000627 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
628 }
629
deadbeefab9b2d12015-10-14 11:33:11 -0700630 void AddDataChannel(cricket::DataChannelType type,
631 const std::string& label,
632 int id) {
633 InternalDataChannelInit config;
634 config.id = id;
635
636 data_channels_.push_back(DataChannel::Create(
637 &data_channel_provider_, cricket::DCT_SCTP, label, config));
638 }
639
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000640 StatsReport* AddCandidateReport(StatsCollector* collector,
641 const cricket::Candidate& candidate,
642 bool local) {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000643 return collector->AddCandidateReport(candidate, local);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000644 }
645
xians@webrtc.org01bda202014-07-09 07:38:38 +0000646 void SetupAndVerifyAudioTrackStats(
647 FakeAudioTrack* audio_track,
648 webrtc::MediaStream* stream,
649 webrtc::StatsCollector* stats,
650 cricket::VoiceChannel* voice_channel,
651 const std::string& vc_name,
652 MockVoiceMediaChannel* media_channel,
653 cricket::VoiceSenderInfo* voice_sender_info,
654 cricket::VoiceReceiverInfo* voice_receiver_info,
655 cricket::VoiceMediaInfo* stats_read,
656 StatsReports* reports) {
657 // A track can't have both sender report and recv report at the same time
658 // for now, this might change in the future though.
659 ASSERT((voice_sender_info == NULL) ^ (voice_receiver_info == NULL));
xians@webrtc.org01bda202014-07-09 07:38:38 +0000660
661 // Instruct the session to return stats containing the transport channel.
662 InitSessionStats(vc_name);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +0000663 EXPECT_CALL(session_, GetTransportStats(_))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000664 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
665 Return(true)));
666
667 // Constructs an ssrc stats update.
668 if (voice_sender_info)
669 stats_read->senders.push_back(*voice_sender_info);
670 if (voice_receiver_info)
671 stats_read->receivers.push_back(*voice_receiver_info);
672
673 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(
674 Return(voice_channel));
675 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
676 EXPECT_CALL(*media_channel, GetStats(_))
677 .WillOnce(DoAll(SetArgPointee<0>(*stats_read), Return(true)));
678
679 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000680 stats->ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +0000681 stats->GetStats(NULL, reports);
682
683 // Verify the existence of the track report.
684 const StatsReport* report = FindNthReportByType(
685 *reports, StatsReport::kStatsReportTypeSsrc, 1);
686 EXPECT_FALSE(report == NULL);
jbauchbe24c942015-06-22 15:06:43 -0700687 EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000688 std::string track_id = ExtractSsrcStatsValue(
689 *reports, StatsReport::kStatsValueNameTrackId);
690 EXPECT_EQ(audio_track->id(), track_id);
691 std::string ssrc_id = ExtractSsrcStatsValue(
692 *reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200693 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000694
fippobec70ab2016-01-28 01:27:15 -0800695 std::string media_type = ExtractSsrcStatsValue(*reports,
696 StatsReport::kStatsValueNameMediaType);
697 EXPECT_EQ("audio", media_type);
698
xians@webrtc.org01bda202014-07-09 07:38:38 +0000699 // Verifies the values in the track report.
700 if (voice_sender_info) {
701 UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info);
702 VerifyVoiceSenderInfoReport(report, *voice_sender_info);
703 }
704 if (voice_receiver_info) {
705 VerifyVoiceReceiverInfoReport(report, *voice_receiver_info);
706 }
707
708 // Verify we get the same result by passing a track to GetStats().
709 StatsReports track_reports; // returned values.
710 stats->GetStats(audio_track, &track_reports);
711 const StatsReport* track_report = FindNthReportByType(
712 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
713 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -0700714 EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
xians@webrtc.org01bda202014-07-09 07:38:38 +0000715 track_id = ExtractSsrcStatsValue(track_reports,
716 StatsReport::kStatsValueNameTrackId);
717 EXPECT_EQ(audio_track->id(), track_id);
718 ssrc_id = ExtractSsrcStatsValue(track_reports,
719 StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200720 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000721 if (voice_sender_info)
722 VerifyVoiceSenderInfoReport(track_report, *voice_sender_info);
723 if (voice_receiver_info)
724 VerifyVoiceReceiverInfoReport(track_report, *voice_receiver_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000725 }
726
kwibergb4d01c42016-04-06 05:15:06 -0700727 void TestCertificateReports(
728 const rtc::FakeSSLCertificate& local_cert,
729 const std::vector<std::string>& local_ders,
kwibergd1fe2812016-04-27 06:47:29 -0700730 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert,
kwibergb4d01c42016-04-06 05:15:06 -0700731 const std::vector<std::string>& remote_ders) {
deadbeefab9b2d12015-10-14 11:33:11 -0700732 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000733
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000734 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000735
736 // Fake stats to process.
737 cricket::TransportChannelStats channel_stats;
738 channel_stats.component = 1;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800739 channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
tkchin7d06a8c2016-04-04 14:10:43 -0700740 channel_stats.ssl_cipher_suite =
741 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000742
743 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -0700744 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +0000745 transport_stats.channel_stats.push_back(channel_stats);
746
deadbeefd59daf82015-10-14 15:02:44 -0700747 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -0700748 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +0000749 transport_stats;
750
deadbeefcbecd352015-09-23 11:50:27 -0700751 // Fake certificate to report
Henrik Boströmd8281982015-08-27 10:12:24 +0200752 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
jbauch555604a2016-04-26 03:13:22 -0700753 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800754 new rtc::FakeSSLIdentity(local_cert))));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000755
756 // Configure MockWebRtcSession
deadbeefcbecd352015-09-23 11:50:27 -0700757 EXPECT_CALL(session_,
758 GetLocalCertificate(transport_stats.transport_name, _))
759 .WillOnce(DoAll(SetArgPointee<1>(local_certificate), Return(true)));
kwibergb4d01c42016-04-06 05:15:06 -0700760 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(
761 transport_stats.transport_name))
762 .WillOnce(Return(remote_cert.release()));
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +0000763 EXPECT_CALL(session_, GetTransportStats(_))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000764 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
765 Return(true)));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000766
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000767 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000768
769 stats.GetStats(NULL, &reports);
770
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000771 const StatsReport* channel_report = FindNthReportByType(
772 reports, StatsReport::kStatsReportTypeComponent, 1);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000773 EXPECT_TRUE(channel_report != NULL);
774
775 // Check local certificate chain.
776 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000777 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000778 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000779 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000780 if (local_ders.size() > 0) {
781 EXPECT_NE(kNotFound, local_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000782 StatsReport::Id id(IdFromCertIdString(local_certificate_id));
783 CheckCertChainReports(reports, local_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000784 } else {
785 EXPECT_EQ(kNotFound, local_certificate_id);
786 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000787
788 // Check remote certificate chain.
789 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000790 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000791 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000792 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000793 if (remote_ders.size() > 0) {
794 EXPECT_NE(kNotFound, remote_certificate_id);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000795 StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
796 CheckCertChainReports(reports, remote_ders, id);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000797 } else {
798 EXPECT_EQ(kNotFound, remote_certificate_id);
799 }
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000800
801 // Check negotiated ciphers.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800802 std::string dtls_cipher_suite =
803 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
804 StatsReport::kStatsValueNameDtlsCipher);
805 EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
tkchin7d06a8c2016-04-04 14:10:43 -0700806 internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800807 dtls_cipher_suite);
808 std::string srtp_crypto_suite =
809 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
810 StatsReport::kStatsValueNameSrtpCipher);
811 EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
812 srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000813 }
wu@webrtc.org97077a32013-10-25 21:18:33 +0000814
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200815 rtc::Thread* const worker_thread_;
816 rtc::Thread* const network_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817 cricket::FakeMediaEngine* media_engine_;
kwibergd1fe2812016-04-27 06:47:29 -0700818 std::unique_ptr<cricket::ChannelManager> channel_manager_;
819 std::unique_ptr<webrtc::MediaControllerInterface> media_controller_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 MockWebRtcSession session_;
deadbeefab9b2d12015-10-14 11:33:11 -0700821 MockPeerConnection pc_;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000822 FakeDataChannelProvider data_channel_provider_;
deadbeefd59daf82015-10-14 15:02:44 -0700823 SessionStats session_stats_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000824 rtc::scoped_refptr<webrtc::MediaStream> stream_;
825 rtc::scoped_refptr<webrtc::VideoTrack> track_;
826 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
deadbeefab9b2d12015-10-14 11:33:11 -0700827 std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828};
829
zhihuang6ba3b192016-05-13 11:46:35 -0700830TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) {
831 const std::string label = "hacks";
832 // The data channel id is from the Config which is -1 initially.
833 const int id = -1;
834 const std::string state = DataChannelInterface::DataStateString(
835 DataChannelInterface::DataState::kConnecting);
836
837 AddDataChannel(cricket::DCT_SCTP, label, id);
838 StatsCollectorForTest stats(&pc_);
839
840 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
841
842 StatsReports reports;
843 stats.GetStats(NULL, &reports);
844
845 const StatsReport* report =
846 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
847
848 std::string value_in_report;
849 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId,
850 &value_in_report));
851}
852
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000853// Verify that ExtractDataInfo populates reports.
854TEST_F(StatsCollectorTest, ExtractDataInfo) {
855 const std::string label = "hacks";
856 const int id = 31337;
857 const std::string state = DataChannelInterface::DataStateString(
858 DataChannelInterface::DataState::kConnecting);
859
deadbeefab9b2d12015-10-14 11:33:11 -0700860 AddDataChannel(cricket::DCT_SCTP, label, id);
861 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000862
863 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
864
865 StatsReports reports;
866 stats.GetStats(NULL, &reports);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000867
868 const StatsReport* report =
869 FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
870
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000871 StatsReport::Id reportId = StatsReport::NewTypedIntId(
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000872 StatsReport::kStatsReportTypeDataChannel, id);
873
874 EXPECT_TRUE(reportId->Equals(report->id()));
875
876 EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000877 EXPECT_EQ(label, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
878 reports,
879 StatsReport::kStatsValueNameLabel));
Peter Boström0c4e06b2015-10-07 12:23:21 +0200880 EXPECT_EQ(rtc::ToString<int64_t>(id),
881 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000882 StatsReport::kStatsValueNameDataChannelId));
883 EXPECT_EQ(state, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
884 reports,
885 StatsReport::kStatsValueNameState));
886 EXPECT_EQ("", ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
887 reports,
888 StatsReport::kStatsValueNameProtocol));
889}
890
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891// This test verifies that 64-bit counters are passed successfully.
892TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
deadbeefab9b2d12015-10-14 11:33:11 -0700893 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000894
deadbeefcbecd352015-09-23 11:50:27 -0700895 EXPECT_CALL(session_, GetLocalCertificate(_, _))
896 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -0700897 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
898 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -0700899
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000900 const char kVideoChannelName[] = "video";
901
902 InitSessionStats(kVideoChannelName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +0000903 EXPECT_CALL(session_, GetTransportStats(_))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000904 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
905 Return(true)));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000906
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000907 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200908 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
909 media_channel, nullptr, kVideoChannelName,
910 false);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000911 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912 cricket::VideoSenderInfo video_sender_info;
913 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000914 // The number of bytes must be larger than 0xFFFFFFFF for this test.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200915 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916 const std::string kBytesSentString("12345678901234");
917
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000918 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000919 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000920
921 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000922 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923 video_sender_info.bytes_sent = kBytesSent;
924 stats_read.senders.push_back(video_sender_info);
925
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000926 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
927 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000928 EXPECT_CALL(*media_channel, GetStats(_))
929 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000930 Return(true)));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000931 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000933 std::string result = ExtractSsrcStatsValue(reports,
934 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935 EXPECT_EQ(kBytesSentString, result);
936}
937
938// Test that BWE information is reported via stats.
939TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
deadbeefab9b2d12015-10-14 11:33:11 -0700940 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000941
deadbeefcbecd352015-09-23 11:50:27 -0700942 EXPECT_CALL(session_, GetLocalCertificate(_, _))
943 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -0700944 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
945 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -0700946
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000947 const char kVideoChannelName[] = "video";
948
949 InitSessionStats(kVideoChannelName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +0000950 EXPECT_CALL(session_, GetTransportStats(_))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000951 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
952 Return(true)));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000953
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000954 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200955 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
956 media_channel, nullptr, kVideoChannelName,
957 false);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000958
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000959 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960 cricket::VideoSenderInfo video_sender_info;
961 cricket::VideoMediaInfo stats_read;
962 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
963 // BWE.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200964 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965 const std::string kBytesSentString("12345678901234");
966
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000967 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000968 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969
970 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000971 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972 video_sender_info.bytes_sent = kBytesSent;
973 stats_read.senders.push_back(video_sender_info);
974 cricket::BandwidthEstimationInfo bwe;
975 const int kTargetEncBitrate = 123456;
976 const std::string kTargetEncBitrateString("123456");
977 bwe.target_enc_bitrate = kTargetEncBitrate;
978 stats_read.bw_estimations.push_back(bwe);
979
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000980 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
981 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000982 EXPECT_CALL(*media_channel, GetStats(_))
983 .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000984
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000985 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000987 std::string result = ExtractSsrcStatsValue(reports,
988 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000989 EXPECT_EQ(kBytesSentString, result);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000990 result = ExtractBweStatsValue(reports,
991 StatsReport::kStatsValueNameTargetEncBitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992 EXPECT_EQ(kTargetEncBitrateString, result);
993}
994
995// This test verifies that an object of type "googSession" always
996// exists in the returned stats.
997TEST_F(StatsCollectorTest, SessionObjectExists) {
deadbeefab9b2d12015-10-14 11:33:11 -0700998 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000999
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001000 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001001 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001003 const StatsReport* session_report = FindNthReportByType(
1004 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 EXPECT_FALSE(session_report == NULL);
1006}
1007
1008// This test verifies that only one object of type "googSession" exists
1009// in the returned stats.
1010TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
deadbeefab9b2d12015-10-14 11:33:11 -07001011 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001012
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001013 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001014 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1015 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001016 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001017 const StatsReport* session_report = FindNthReportByType(
1018 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019 EXPECT_FALSE(session_report == NULL);
1020 session_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001021 reports, StatsReport::kStatsReportTypeSession, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001022 EXPECT_EQ(NULL, session_report);
1023}
1024
1025// This test verifies that the empty track report exists in the returned stats
1026// without calling StatsCollector::UpdateStats.
1027TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
deadbeefab9b2d12015-10-14 11:33:11 -07001028 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001029
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001030 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001031 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1032 media_channel, nullptr, "video", false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001033 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001034 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001036 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001037 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 stats.GetStats(NULL, &reports);
1039 EXPECT_EQ((size_t)1, reports.size());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001040 EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
jbauchbe24c942015-06-22 15:06:43 -07001041 EXPECT_EQ(0, reports[0]->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001042
1043 std::string trackValue =
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001044 ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001046 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001047 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001048}
1049
1050// This test verifies that the empty track report exists in the returned stats
1051// when StatsCollector::UpdateStats is called with ssrc stats.
1052TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
deadbeefab9b2d12015-10-14 11:33:11 -07001053 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001054
deadbeefcbecd352015-09-23 11:50:27 -07001055 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1056 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001057 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1058 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001059
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001060 const char kVideoChannelName[] = "video";
1061 InitSessionStats(kVideoChannelName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001062 EXPECT_CALL(session_, GetTransportStats(_))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001063 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1064 Return(true)));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001065
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001066 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001067 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1068 media_channel, nullptr, kVideoChannelName,
1069 false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001070 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001071 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001072
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073 // Constructs an ssrc stats update.
1074 cricket::VideoSenderInfo video_sender_info;
1075 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001076 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001077
1078 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001079 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001080 video_sender_info.bytes_sent = kBytesSent;
1081 stats_read.senders.push_back(video_sender_info);
1082
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001083 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1084 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001085 EXPECT_CALL(*media_channel, GetStats(_))
1086 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001088
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001089 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001090 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001091 stats.GetStats(NULL, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001092 // |reports| should contain at least one session report, one track report,
1093 // and one ssrc report.
1094 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001095 const StatsReport* track_report = FindNthReportByType(
1096 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001097 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001099 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001100 reports.clear();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001101 stats.GetStats(track_, &reports);
1102 // |reports| should contain at least one session report, one track report,
1103 // and one ssrc report.
1104 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001105 track_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001106 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001107 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001108 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001109
1110 std::string ssrc_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001111 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001112 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001113
1114 std::string track_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001115 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001116 EXPECT_EQ(kLocalTrackId, track_id);
fippobec70ab2016-01-28 01:27:15 -08001117
1118 std::string media_type = ExtractSsrcStatsValue(reports,
1119 StatsReport::kStatsValueNameMediaType);
1120 EXPECT_EQ("video", media_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001121}
1122
1123// This test verifies that an SSRC object has the identifier of a Transport
1124// stats object, and that this transport stats object exists in stats.
1125TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
deadbeefab9b2d12015-10-14 11:33:11 -07001126 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001127
deadbeefcbecd352015-09-23 11:50:27 -07001128 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1129 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001130 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1131 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001132
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001133 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001134 // The transport_name known by the video channel.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001135 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001136 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1137 media_channel, nullptr, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001138 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001139 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001141 // Constructs an ssrc stats update.
1142 cricket::VideoSenderInfo video_sender_info;
1143 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001144 const int64_t kBytesSent = 12345678901234LL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001145
1146 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001147 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148 video_sender_info.bytes_sent = kBytesSent;
1149 stats_read.senders.push_back(video_sender_info);
1150
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001151 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1152 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001153 EXPECT_CALL(*media_channel, GetStats(_))
1154 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001156
wu@webrtc.org97077a32013-10-25 21:18:33 +00001157 InitSessionStats(kVcName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001158 EXPECT_CALL(session_, GetTransportStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001159 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1160 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001161
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001162 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001163 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164 stats.GetStats(NULL, &reports);
1165 std::string transport_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001166 StatsReport::kStatsReportTypeSsrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001167 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001168 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001169 ASSERT_NE(kNotFound, transport_id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001170 // Transport id component ID will always be 1.
1171 // This has assumptions about how the ID is constructed. As is, this is
1172 // OK since this is for testing purposes only, but if we ever need this
1173 // in production, we should add a generic method that does this.
1174 size_t index = transport_id.find('-');
1175 ASSERT_NE(std::string::npos, index);
1176 std::string content = transport_id.substr(index + 1);
1177 index = content.rfind('-');
1178 ASSERT_NE(std::string::npos, index);
1179 content = content.substr(0, index);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001180 StatsReport::Id id(StatsReport::NewComponentId(content, 1));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +00001181 ASSERT_EQ(transport_id, id->ToString());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001182 const StatsReport* transport_report = FindReportById(reports, id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183 ASSERT_FALSE(transport_report == NULL);
1184}
1185
wu@webrtc.org97077a32013-10-25 21:18:33 +00001186// This test verifies that a remote stats object will not be created for
1187// an outgoing SSRC where remote stats are not returned.
1188TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
deadbeefab9b2d12015-10-14 11:33:11 -07001189 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001190
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001191 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001192 // The transport_name known by the video channel.
wu@webrtc.org97077a32013-10-25 21:18:33 +00001193 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001194 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1195 media_channel, nullptr, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001196 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001197 stats.AddStream(stream_);
1198
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001199 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001200 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001201 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001202 const StatsReport* remote_report = FindNthReportByType(reports,
1203 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001204 EXPECT_TRUE(remote_report == NULL);
1205}
1206
1207// This test verifies that a remote stats object will be created for
1208// an outgoing SSRC where stats are returned.
1209TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
deadbeefab9b2d12015-10-14 11:33:11 -07001210 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001211
deadbeefcbecd352015-09-23 11:50:27 -07001212 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1213 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001214 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1215 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001216
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001217 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001218 // The transport_name known by the video channel.
wu@webrtc.org97077a32013-10-25 21:18:33 +00001219 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001220 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1221 media_channel, nullptr, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001222 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001223 stats.AddStream(stream_);
1224
wu@webrtc.org97077a32013-10-25 21:18:33 +00001225 // Instruct the session to return stats containing the transport channel.
1226 InitSessionStats(kVcName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001227 EXPECT_CALL(session_, GetTransportStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001228 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1229 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001230
1231 // Constructs an ssrc stats update.
1232 cricket::VideoMediaInfo stats_read;
1233
1234 cricket::SsrcReceiverInfo remote_ssrc_stats;
1235 remote_ssrc_stats.timestamp = 12345.678;
1236 remote_ssrc_stats.ssrc = kSsrcOfTrack;
1237 cricket::VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001238 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001239 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
1240 stats_read.senders.push_back(video_sender_info);
1241
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001242 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1243 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001244 EXPECT_CALL(*media_channel, GetStats(_))
1245 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
wu@webrtc.org97077a32013-10-25 21:18:33 +00001246 Return(true)));
1247
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001248 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001249 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001250 stats.GetStats(NULL, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001251
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001252 const StatsReport* remote_report = FindNthReportByType(reports,
1253 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001254 EXPECT_FALSE(remote_report == NULL);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +00001255 EXPECT_EQ(12345.678, remote_report->timestamp());
wu@webrtc.org97077a32013-10-25 21:18:33 +00001256}
1257
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001258// This test verifies that the empty track report exists in the returned stats
1259// when StatsCollector::UpdateStats is called with ssrc stats.
1260TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
deadbeefab9b2d12015-10-14 11:33:11 -07001261 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001262
deadbeefcbecd352015-09-23 11:50:27 -07001263 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1264 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001265 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1266 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001267
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001268 const char kVideoChannelName[] = "video";
1269 InitSessionStats(kVideoChannelName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001270 EXPECT_CALL(session_, GetTransportStats(_))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001271 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1272 Return(true)));
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001273
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001274 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001275 cricket::VideoChannel video_channel(worker_thread_, network_thread_,
1276 media_channel, nullptr, kVideoChannelName,
1277 false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001278 AddIncomingVideoTrackStats();
1279 stats.AddStream(stream_);
1280
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001281 // Constructs an ssrc stats update.
1282 cricket::VideoReceiverInfo video_receiver_info;
1283 cricket::VideoMediaInfo stats_read;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001284 const int64_t kNumOfPacketsConcealed = 54321;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001285
1286 // Construct a stats value to read.
1287 video_receiver_info.add_ssrc(1234);
pbos@webrtc.org1ed62242015-02-19 13:57:03 +00001288 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001289 stats_read.receivers.push_back(video_receiver_info);
1290
1291 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1292 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001293 EXPECT_CALL(*media_channel, GetStats(_))
1294 .WillOnce(DoAll(SetArgPointee<0>(stats_read),
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001295 Return(true)));
1296
1297 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001298 StatsReports reports;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001299 stats.GetStats(NULL, &reports);
1300 // |reports| should contain at least one session report, one track report,
1301 // and one ssrc report.
1302 EXPECT_LE(static_cast<size_t>(3), reports.size());
1303 const StatsReport* track_report = FindNthReportByType(
1304 reports, StatsReport::kStatsReportTypeTrack, 1);
1305 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001306 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001307
1308 std::string ssrc_id = ExtractSsrcStatsValue(
1309 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001310 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001311
1312 std::string track_id = ExtractSsrcStatsValue(
1313 reports, StatsReport::kStatsValueNameTrackId);
1314 EXPECT_EQ(kRemoteTrackId, track_id);
1315}
1316
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001317// This test verifies the Ice Candidate report should contain the correct
1318// information from local/remote candidates.
1319TEST_F(StatsCollectorTest, IceCandidateReport) {
deadbeefab9b2d12015-10-14 11:33:11 -07001320 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001321
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001322 StatsReports reports; // returned values.
1323
1324 const int local_port = 2000;
1325 const char local_ip[] = "192.168.0.1";
1326 const int remote_port = 2001;
1327 const char remote_ip[] = "192.168.0.2";
1328
1329 rtc::SocketAddress local_address(local_ip, local_port);
1330 rtc::SocketAddress remote_address(remote_ip, remote_port);
1331 rtc::AdapterType network_type = rtc::ADAPTER_TYPE_ETHERNET;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001332 uint32_t priority = 1000;
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001333
1334 cricket::Candidate c;
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001335 ASSERT(c.id().length() > 0);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001336 c.set_type(cricket::LOCAL_PORT_TYPE);
1337 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
1338 c.set_address(local_address);
1339 c.set_priority(priority);
1340 c.set_network_type(network_type);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001341 std::string report_id = AddCandidateReport(&stats, c, true)->id()->ToString();
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001342 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001343
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001344 c = cricket::Candidate();
1345 ASSERT(c.id().length() > 0);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001346 c.set_type(cricket::PRFLX_PORT_TYPE);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001347 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001348 c.set_address(remote_address);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001349 c.set_priority(priority);
1350 c.set_network_type(network_type);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +00001351 report_id = AddCandidateReport(&stats, c, false)->id()->ToString();
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001352 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001353
1354 stats.GetStats(NULL, &reports);
1355
1356 // Verify the local candidate report is populated correctly.
1357 EXPECT_EQ(
1358 local_ip,
1359 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1360 StatsReport::kStatsValueNameCandidateIPAddress));
1361 EXPECT_EQ(
1362 rtc::ToString<int>(local_port),
1363 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1364 StatsReport::kStatsValueNameCandidatePortNumber));
1365 EXPECT_EQ(
1366 cricket::UDP_PROTOCOL_NAME,
1367 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1368 StatsReport::kStatsValueNameCandidateTransportType));
1369 EXPECT_EQ(
1370 rtc::ToString<int>(priority),
1371 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1372 StatsReport::kStatsValueNameCandidatePriority));
1373 EXPECT_EQ(
1374 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1375 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1376 StatsReport::kStatsValueNameCandidateType));
1377 EXPECT_EQ(
1378 AdapterTypeToStatsType(network_type),
1379 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1380 StatsReport::kStatsValueNameCandidateNetworkType));
1381
1382 // Verify the remote candidate report is populated correctly.
1383 EXPECT_EQ(remote_ip,
1384 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1385 reports,
1386 StatsReport::kStatsValueNameCandidateIPAddress));
1387 EXPECT_EQ(rtc::ToString<int>(remote_port),
1388 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1389 reports,
1390 StatsReport::kStatsValueNameCandidatePortNumber));
1391 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1392 ExtractStatsValue(
1393 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1394 StatsReport::kStatsValueNameCandidateTransportType));
1395 EXPECT_EQ(rtc::ToString<int>(priority),
1396 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1397 reports,
1398 StatsReport::kStatsValueNameCandidatePriority));
1399 EXPECT_EQ(
1400 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1401 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1402 reports, StatsReport::kStatsValueNameCandidateType));
1403 EXPECT_EQ(kNotFound,
1404 ExtractStatsValue(
1405 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1406 StatsReport::kStatsValueNameCandidateNetworkType));
1407}
1408
wu@webrtc.org4551b792013-10-09 15:37:36 +00001409// This test verifies that all chained certificates are correctly
1410// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001411TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001412 // Build local certificate chain.
1413 std::vector<std::string> local_ders(5);
1414 local_ders[0] = "These";
1415 local_ders[1] = "are";
1416 local_ders[2] = "some";
1417 local_ders[3] = "der";
1418 local_ders[4] = "values";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001419 rtc::FakeSSLCertificate local_cert(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001420
1421 // Build remote certificate chain
1422 std::vector<std::string> remote_ders(4);
1423 remote_ders[0] = "A";
1424 remote_ders[1] = "non-";
1425 remote_ders[2] = "intersecting";
1426 remote_ders[3] = "set";
kwibergd1fe2812016-04-27 06:47:29 -07001427 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001428 new rtc::FakeSSLCertificate(DersToPems(remote_ders)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001429
kwibergb4d01c42016-04-06 05:15:06 -07001430 TestCertificateReports(local_cert, local_ders, std::move(remote_cert),
1431 remote_ders);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001432}
1433
1434// This test verifies that all certificates without chains are correctly
1435// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001436TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001437 // Build local certificate.
1438 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001439 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001440
1441 // Build remote certificate.
1442 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001443 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001444 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001445
1446 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001447 std::move(remote_cert),
1448 std::vector<std::string>(1, remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001449}
1450
1451// This test verifies that the stats are generated correctly when no
1452// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001453TEST_F(StatsCollectorTest, NoTransport) {
deadbeefab9b2d12015-10-14 11:33:11 -07001454 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001455
deadbeefcbecd352015-09-23 11:50:27 -07001456 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1457 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001458 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1459 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001460
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001461 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001462
1463 // Fake stats to process.
1464 cricket::TransportChannelStats channel_stats;
1465 channel_stats.component = 1;
1466
1467 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001468 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +00001469 transport_stats.channel_stats.push_back(channel_stats);
1470
deadbeefd59daf82015-10-14 15:02:44 -07001471 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001472 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +00001473 transport_stats;
1474
1475 // Configure MockWebRtcSession
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001476 EXPECT_CALL(session_, GetTransportStats(_))
wu@webrtc.org4551b792013-10-09 15:37:36 +00001477 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
1478 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001479
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001480 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001481 stats.GetStats(NULL, &reports);
1482
1483 // Check that the local certificate is absent.
1484 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001485 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001486 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001487 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001488 ASSERT_EQ(kNotFound, local_certificate_id);
1489
1490 // Check that the remote certificate is absent.
1491 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001492 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001493 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001494 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001495 ASSERT_EQ(kNotFound, remote_certificate_id);
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001496
1497 // Check that the negotiated ciphers are absent.
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -08001498 std::string dtls_cipher_suite =
1499 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1500 StatsReport::kStatsValueNameDtlsCipher);
1501 ASSERT_EQ(kNotFound, dtls_cipher_suite);
1502 std::string srtp_crypto_suite =
1503 ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
1504 StatsReport::kStatsValueNameSrtpCipher);
1505 ASSERT_EQ(kNotFound, srtp_crypto_suite);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001506}
1507
1508// This test verifies that the stats are generated correctly when the transport
1509// does not have any certificates.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001510TEST_F(StatsCollectorTest, NoCertificates) {
deadbeefab9b2d12015-10-14 11:33:11 -07001511 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001512
deadbeefcbecd352015-09-23 11:50:27 -07001513 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1514 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001515 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1516 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001517
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001518 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001519
1520 // Fake stats to process.
1521 cricket::TransportChannelStats channel_stats;
1522 channel_stats.component = 1;
1523
1524 cricket::TransportStats transport_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001525 transport_stats.transport_name = "audio";
wu@webrtc.org4551b792013-10-09 15:37:36 +00001526 transport_stats.channel_stats.push_back(channel_stats);
1527
deadbeefd59daf82015-10-14 15:02:44 -07001528 SessionStats session_stats;
deadbeefcbecd352015-09-23 11:50:27 -07001529 session_stats.transport_stats[transport_stats.transport_name] =
wu@webrtc.org4551b792013-10-09 15:37:36 +00001530 transport_stats;
1531
1532 // Fake transport object.
kwibergd1fe2812016-04-27 06:47:29 -07001533 std::unique_ptr<cricket::FakeTransport> transport(
deadbeefcbecd352015-09-23 11:50:27 -07001534 new cricket::FakeTransport(transport_stats.transport_name));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001535
1536 // Configure MockWebRtcSession
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001537 EXPECT_CALL(session_, GetTransportStats(_))
wu@webrtc.org4551b792013-10-09 15:37:36 +00001538 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
1539 Return(true)));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001540 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001541 stats.GetStats(NULL, &reports);
1542
1543 // Check that the local certificate is absent.
1544 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001545 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001546 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001547 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001548 ASSERT_EQ(kNotFound, local_certificate_id);
1549
1550 // Check that the remote certificate is absent.
1551 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001552 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001553 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001554 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001555 ASSERT_EQ(kNotFound, remote_certificate_id);
1556}
1557
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001558// This test verifies that a remote certificate with an unsupported digest
1559// algorithm is correctly ignored.
1560TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1561 // Build a local certificate.
1562 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001563 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001564
1565 // Build a remote certificate with an unsupported digest algorithm.
1566 std::string remote_der = "This is somebody else's der.";
kwibergd1fe2812016-04-27 06:47:29 -07001567 std::unique_ptr<rtc::FakeSSLCertificate> remote_cert(
kwibergb4d01c42016-04-06 05:15:06 -07001568 new rtc::FakeSSLCertificate(DerToPem(remote_der)));
1569 remote_cert->set_digest_algorithm("foobar");
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001570
1571 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
kwibergb4d01c42016-04-06 05:15:06 -07001572 std::move(remote_cert), std::vector<std::string>());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001573}
1574
zhihuang6ba3b192016-05-13 11:46:35 -07001575// This test verifies that the audio/video related stats which are -1 initially
1576// will be filtered out.
1577TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) {
1578 StatsCollectorForTest stats(&pc_);
1579
1580 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1581 .WillRepeatedly(Return(false));
1582 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1583 .WillRepeatedly(Return(nullptr));
1584
1585 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1586 // The transport_name known by the voice channel.
1587 const std::string kVcName("vcname");
1588 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1589 media_engine_, media_channel, nullptr,
1590 kVcName, false);
1591
1592 // Create a local stream with a local audio track and adds it to the stats.
1593 if (stream_ == NULL)
1594 stream_ = webrtc::MediaStream::Create("streamlabel");
1595
1596 rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track(
1597 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId));
1598 stream_->AddTrack(local_track);
1599 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
1600 .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
1601 stats.AddStream(stream_);
1602 stats.AddLocalAudioTrack(local_track.get(), kSsrcOfTrack);
1603
1604 // Create a remote stream with a remote audio track and adds it to the stats.
1605 rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
1606 webrtc::MediaStream::Create("remotestreamlabel"));
1607 rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track(
1608 new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId));
1609 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
1610 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
1611 remote_stream->AddTrack(remote_track);
1612 stats.AddStream(remote_stream);
1613
1614 // Instruct the session to return stats containing the transport channel.
1615 InitSessionStats(kVcName);
1616 EXPECT_CALL(session_, GetTransportStats(_))
1617 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), Return(true)));
1618
1619 cricket::VoiceSenderInfo voice_sender_info;
1620 voice_sender_info.add_ssrc(kSsrcOfTrack);
1621 // These values are set to -1 initially in audio_send_stream.
1622 // The voice_sender_info will read the values from audio_send_stream.
1623 voice_sender_info.rtt_ms = -1;
1624 voice_sender_info.packets_lost = -1;
1625 voice_sender_info.jitter_ms = -1;
1626
1627 // Some of the contents in |voice_sender_info| needs to be updated from the
1628 // |audio_track_|.
1629 UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info);
1630
1631 cricket::VoiceReceiverInfo voice_receiver_info;
1632 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1633 voice_receiver_info.capture_start_ntp_time_ms = -1;
1634 voice_receiver_info.audio_level = -1;
1635
1636 // Constructs an ssrc stats update.
1637 cricket::VoiceMediaInfo stats_read;
1638 stats_read.senders.push_back(voice_sender_info);
1639 stats_read.receivers.push_back(voice_receiver_info);
1640
1641 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1642 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1643 EXPECT_CALL(*media_channel, GetStats(_))
1644 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read), Return(true)));
1645
1646 StatsReports reports;
1647 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1648
1649 // Get stats for the local track.
1650 stats.GetStats(local_track.get(), &reports);
1651 const StatsReport* report =
1652 FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
1653 EXPECT_TRUE(report);
1654 // The -1 will not be added to the stats report.
1655 std::string value_in_report;
1656 EXPECT_FALSE(
1657 GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report));
1658 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost,
1659 &value_in_report));
1660 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived,
1661 &value_in_report));
1662 EXPECT_FALSE(GetValue(report,
1663 StatsReport::kStatsValueNameEchoCancellationQualityMin,
1664 &value_in_report));
1665 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian,
1666 &value_in_report));
1667 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev,
1668 &value_in_report));
1669
1670 // Get stats for the remote track.
1671 reports.clear();
1672 stats.GetStats(remote_track.get(), &reports);
1673 report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1);
1674 EXPECT_TRUE(report);
1675 EXPECT_FALSE(GetValue(report,
1676 StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
1677 &value_in_report));
1678 EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel,
1679 &value_in_report));
1680}
1681
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001682// This test verifies that a local stats object can get statistics via
1683// AudioTrackInterface::GetStats() method.
1684TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
deadbeefab9b2d12015-10-14 11:33:11 -07001685 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001686
deadbeefcbecd352015-09-23 11:50:27 -07001687 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1688 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001689 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1690 .WillRepeatedly(Return(nullptr));
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001691
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001692 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001693 // The transport_name known by the voice channel.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001694 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001695 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1696 media_engine_, media_channel, nullptr,
1697 kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001698 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001699 stats.AddStream(stream_);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001700 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001701
1702 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001703 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001704
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001705 cricket::VoiceMediaInfo stats_read;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001706 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001707 SetupAndVerifyAudioTrackStats(
1708 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1709 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001710
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001711 // Verify that there is no remote report for the local audio track because
1712 // we did not set it up.
1713 const StatsReport* remote_report = FindNthReportByType(reports,
1714 StatsReport::kStatsReportTypeRemoteSsrc, 1);
1715 EXPECT_TRUE(remote_report == NULL);
1716}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001717
1718// This test verifies that audio receive streams populate stats reports
1719// correctly.
1720TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07001721 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001722
deadbeefcbecd352015-09-23 11:50:27 -07001723 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1724 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001725 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1726 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001727
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001728 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001729 // The transport_name known by the voice channel.
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001730 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001731 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1732 media_engine_, media_channel, nullptr,
1733 kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001734 AddIncomingAudioTrackStats();
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001735 stats.AddStream(stream_);
1736
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001737 cricket::VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001738 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001739 voice_receiver_info.codec_name = "fake_codec";
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001740
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001741 cricket::VoiceMediaInfo stats_read;
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001742 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001743 SetupAndVerifyAudioTrackStats(
1744 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1745 media_channel, NULL, &voice_receiver_info, &stats_read, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001746}
1747
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001748// This test verifies that a local stats object won't update its statistics
1749// after a RemoveLocalAudioTrack() call.
1750TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
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));
deadbeefcbecd352015-09-23 11:50:27 -07001757
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");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001761 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1762 media_engine_, media_channel, nullptr,
1763 kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001764 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001765 stats.AddStream(stream_);
1766 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1767
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001768 // Instruct the session to return stats containing the transport channel.
1769 InitSessionStats(kVcName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001770 EXPECT_CALL(session_, GetTransportStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001771 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1772 Return(true)));
1773
1774 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1775 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001776 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001777
1778 // Constructs an ssrc stats update.
1779 cricket::VoiceMediaInfo stats_read;
1780 stats_read.senders.push_back(voice_sender_info);
1781
1782 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1783 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1784 EXPECT_CALL(*media_channel, GetStats(_))
1785 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1786 Return(true)));
1787
1788 StatsReports reports; // returned values.
1789 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1790 stats.GetStats(NULL, &reports);
1791
1792 // The report will exist since we don't remove them in RemoveStream().
1793 const StatsReport* report = FindNthReportByType(
1794 reports, StatsReport::kStatsReportTypeSsrc, 1);
1795 EXPECT_FALSE(report == NULL);
jbauchbe24c942015-06-22 15:06:43 -07001796 EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001797 std::string track_id = ExtractSsrcStatsValue(
1798 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001799 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001800 std::string ssrc_id = ExtractSsrcStatsValue(
1801 reports, StatsReport::kStatsValueNameSsrc);
Peter Boström0c4e06b2015-10-07 12:23:21 +02001802 EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001803
1804 // Verifies the values in the track report, no value will be changed by the
1805 // AudioTrackInterface::GetSignalValue() and
1806 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1807 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1808}
1809
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001810// This test verifies that when ongoing and incoming audio tracks are using
1811// the same ssrc, they populate stats reports correctly.
1812TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
deadbeefab9b2d12015-10-14 11:33:11 -07001813 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001814
deadbeefcbecd352015-09-23 11:50:27 -07001815 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1816 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001817 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1818 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001819
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001820 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001821 // The transport_name known by the voice channel.
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001822 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001823 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1824 media_engine_, media_channel, nullptr,
1825 kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001826
1827 // Create a local stream with a local audio track and adds it to the stats.
1828 AddOutgoingAudioTrackStats();
1829 stats.AddStream(stream_);
1830 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1831
1832 // Create a remote stream with a remote audio track and adds it to the stats.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001833 rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001834 webrtc::MediaStream::Create("remotestreamlabel"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001835 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1836 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001837 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +00001838 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001839 remote_stream->AddTrack(remote_track);
1840 stats.AddStream(remote_stream);
1841
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001842 // Instruct the session to return stats containing the transport channel.
1843 InitSessionStats(kVcName);
pthatcher@webrtc.orgc04a97f2015-03-16 19:31:40 +00001844 EXPECT_CALL(session_, GetTransportStats(_))
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001845 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1846 Return(true)));
1847
1848 cricket::VoiceSenderInfo voice_sender_info;
1849 InitVoiceSenderInfo(&voice_sender_info);
1850
1851 // Some of the contents in |voice_sender_info| needs to be updated from the
1852 // |audio_track_|.
1853 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info);
1854
1855 cricket::VoiceReceiverInfo voice_receiver_info;
1856 InitVoiceReceiverInfo(&voice_receiver_info);
1857
1858 // Constructs an ssrc stats update.
1859 cricket::VoiceMediaInfo stats_read;
1860 stats_read.senders.push_back(voice_sender_info);
1861 stats_read.receivers.push_back(voice_receiver_info);
1862
1863 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1864 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1865 EXPECT_CALL(*media_channel, GetStats(_))
1866 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1867 Return(true)));
1868
1869 StatsReports reports; // returned values.
1870 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1871
1872 // Get stats for the local track.
1873 stats.GetStats(audio_track_.get(), &reports);
1874 const StatsReport* track_report = FindNthReportByType(
1875 reports, StatsReport::kStatsReportTypeSsrc, 1);
1876 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001877 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001878 std::string track_id = ExtractSsrcStatsValue(
1879 reports, StatsReport::kStatsValueNameTrackId);
1880 EXPECT_EQ(kLocalTrackId, track_id);
1881 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1882
1883 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001884 reports.clear();
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001885 stats.GetStats(remote_track.get(), &reports);
1886 track_report = FindNthReportByType(reports,
1887 StatsReport::kStatsReportTypeSsrc, 1);
1888 EXPECT_TRUE(track_report);
jbauchbe24c942015-06-22 15:06:43 -07001889 EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001890 track_id = ExtractSsrcStatsValue(reports,
1891 StatsReport::kStatsValueNameTrackId);
1892 EXPECT_EQ(kRemoteTrackId, track_id);
1893 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1894}
1895
xians@webrtc.org01bda202014-07-09 07:38:38 +00001896// This test verifies that when two outgoing audio tracks are using the same
1897// ssrc at different times, they populate stats reports correctly.
1898// TODO(xians): Figure out if it is possible to encapsulate the setup and
1899// avoid duplication of code in test cases.
1900TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) {
deadbeefab9b2d12015-10-14 11:33:11 -07001901 StatsCollectorForTest stats(&pc_);
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001902
deadbeefcbecd352015-09-23 11:50:27 -07001903 EXPECT_CALL(session_, GetLocalCertificate(_, _))
1904 .WillRepeatedly(Return(false));
kwibergb4d01c42016-04-06 05:15:06 -07001905 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
1906 .WillRepeatedly(Return(nullptr));
deadbeefcbecd352015-09-23 11:50:27 -07001907
xians@webrtc.org01bda202014-07-09 07:38:38 +00001908 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
deadbeefcbecd352015-09-23 11:50:27 -07001909 // The transport_name known by the voice channel.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001910 const std::string kVcName("vcname");
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001911 cricket::VoiceChannel voice_channel(worker_thread_, network_thread_,
1912 media_engine_, media_channel, nullptr,
1913 kVcName, false);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001914
1915 // Create a local stream with a local audio track and adds it to the stats.
1916 AddOutgoingAudioTrackStats();
1917 stats.AddStream(stream_);
1918 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
1919
1920 cricket::VoiceSenderInfo voice_sender_info;
1921 voice_sender_info.add_ssrc(kSsrcOfTrack);
1922
1923 cricket::VoiceMediaInfo stats_read;
1924 StatsReports reports; // returned values.
1925 SetupAndVerifyAudioTrackStats(
1926 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1927 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
1928
1929 // Remove the previous audio track from the stream.
1930 stream_->RemoveTrack(audio_track_.get());
1931 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1932
1933 // Create a new audio track and adds it to the stream and stats.
1934 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001935 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1936 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
xians@webrtc.org01bda202014-07-09 07:38:38 +00001937 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
1938 .WillOnce(DoAll(SetArgPointee<1>(kNewTrackId), Return(true)));
1939 stream_->AddTrack(new_audio_track);
1940
1941 stats.AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +00001942 stats.ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +00001943 cricket::VoiceSenderInfo new_voice_sender_info;
1944 InitVoiceSenderInfo(&new_voice_sender_info);
1945 cricket::VoiceMediaInfo new_stats_read;
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001946 reports.clear();
xians@webrtc.org01bda202014-07-09 07:38:38 +00001947 SetupAndVerifyAudioTrackStats(
1948 new_audio_track.get(), stream_.get(), &stats, &voice_channel, kVcName,
1949 media_channel, &new_voice_sender_info, NULL, &new_stats_read, &reports);
1950}
1951
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001952} // namespace webrtc