blob: 71b37976cccd57160885a74ced731eca07817cf6 [file] [log] [blame]
hbosd565b732016-08-30 14:04:35 -07001/*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "pc/rtcstatscollector.h"
hbosd565b732016-08-30 14:04:35 -070012
hbos9e302742017-01-20 02:47:10 -080013#include <initializer_list>
hbosd565b732016-08-30 14:04:35 -070014#include <memory>
hbosda389e32016-10-25 10:55:08 -070015#include <ostream>
hbosd565b732016-08-30 14:04:35 -070016#include <string>
Steve Anton36b29d12017-10-30 09:57:42 -070017#include <utility>
hbosd565b732016-08-30 14:04:35 -070018#include <vector>
19
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/jsepsessiondescription.h"
21#include "api/rtpparameters.h"
22#include "api/stats/rtcstats_objects.h"
23#include "api/stats/rtcstatsreport.h"
24#include "api/test/mock_rtpreceiver.h"
25#include "api/test/mock_rtpsender.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "media/base/fakemediaengine.h"
27#include "media/base/test/mock_mediachannel.h"
28#include "p2p/base/p2pconstants.h"
29#include "p2p/base/port.h"
30#include "pc/mediastream.h"
31#include "pc/mediastreamtrack.h"
32#include "pc/test/mock_datachannel.h"
33#include "pc/test/mock_peerconnection.h"
34#include "pc/test/mock_webrtcsession.h"
35#include "pc/test/rtcstatsobtainer.h"
36#include "rtc_base/checks.h"
37#include "rtc_base/fakeclock.h"
38#include "rtc_base/fakesslidentity.h"
39#include "rtc_base/gunit.h"
40#include "rtc_base/logging.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "rtc_base/thread_checker.h"
42#include "rtc_base/timedelta.h"
43#include "rtc_base/timeutils.h"
hbosd565b732016-08-30 14:04:35 -070044
hbos6ab97ce2016-10-03 14:16:56 -070045using testing::_;
46using testing::Invoke;
hbosd565b732016-08-30 14:04:35 -070047using testing::Return;
hbos6ded1902016-11-01 01:50:46 -070048using testing::ReturnNull;
hbosd565b732016-08-30 14:04:35 -070049using testing::ReturnRef;
hbos6ded1902016-11-01 01:50:46 -070050using testing::SetArgPointee;
hbosd565b732016-08-30 14:04:35 -070051
52namespace webrtc {
53
hbosda389e32016-10-25 10:55:08 -070054// These are used by gtest code, such as if |EXPECT_EQ| fails.
55void PrintTo(const RTCCertificateStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070056 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070057}
58
hbos0adb8282016-11-23 02:32:06 -080059void PrintTo(const RTCCodecStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070060 *os << stats.ToJson();
hbos0adb8282016-11-23 02:32:06 -080061}
62
hbosda389e32016-10-25 10:55:08 -070063void PrintTo(const RTCDataChannelStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070064 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070065}
66
67void PrintTo(const RTCIceCandidatePairStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070068 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070069}
70
71void PrintTo(const RTCLocalIceCandidateStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070072 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070073}
74
75void PrintTo(const RTCRemoteIceCandidateStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070076 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070077}
78
79void PrintTo(const RTCPeerConnectionStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070080 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070081}
82
hbos09bc1282016-11-08 06:29:22 -080083void PrintTo(const RTCMediaStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070084 *os << stats.ToJson();
hbos09bc1282016-11-08 06:29:22 -080085}
86
87void PrintTo(const RTCMediaStreamTrackStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070088 *os << stats.ToJson();
hbos09bc1282016-11-08 06:29:22 -080089}
90
hboseeafe942016-11-01 03:00:17 -070091void PrintTo(const RTCInboundRTPStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070092 *os << stats.ToJson();
hboseeafe942016-11-01 03:00:17 -070093}
94
hbos6ded1902016-11-01 01:50:46 -070095void PrintTo(const RTCOutboundRTPStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070096 *os << stats.ToJson();
hbos6ded1902016-11-01 01:50:46 -070097}
98
hbosda389e32016-10-25 10:55:08 -070099void PrintTo(const RTCTransportStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -0700100 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -0700101}
102
hbosc82f2e12016-09-05 01:36:50 -0700103namespace {
104
105const int64_t kGetStatsReportTimeoutMs = 1000;
deadbeefac22f702017-01-12 21:59:29 -0800106const bool kDefaultRtcpMuxRequired = true;
deadbeef7af91dd2016-12-13 11:29:11 -0800107const bool kDefaultSrtpRequired = true;
hbosc82f2e12016-09-05 01:36:50 -0700108
hbos6ab97ce2016-10-03 14:16:56 -0700109struct CertificateInfo {
110 rtc::scoped_refptr<rtc::RTCCertificate> certificate;
111 std::vector<std::string> ders;
112 std::vector<std::string> pems;
113 std::vector<std::string> fingerprints;
114};
115
116std::unique_ptr<CertificateInfo> CreateFakeCertificateAndInfoFromDers(
117 const std::vector<std::string>& ders) {
118 RTC_CHECK(!ders.empty());
119 std::unique_ptr<CertificateInfo> info(new CertificateInfo());
120 info->ders = ders;
121 for (const std::string& der : ders) {
122 info->pems.push_back(rtc::SSLIdentity::DerToPem(
123 "CERTIFICATE",
124 reinterpret_cast<const unsigned char*>(der.c_str()),
125 der.length()));
126 }
127 info->certificate =
128 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
129 new rtc::FakeSSLIdentity(rtc::FakeSSLCertificate(info->pems))));
130 // Strip header/footer and newline characters of PEM strings.
131 for (size_t i = 0; i < info->pems.size(); ++i) {
132 rtc::replace_substrs("-----BEGIN CERTIFICATE-----", 27,
133 "", 0, &info->pems[i]);
134 rtc::replace_substrs("-----END CERTIFICATE-----", 25,
135 "", 0, &info->pems[i]);
136 rtc::replace_substrs("\n", 1,
137 "", 0, &info->pems[i]);
138 }
139 // Fingerprint of leaf certificate.
140 std::unique_ptr<rtc::SSLFingerprint> fp(
141 rtc::SSLFingerprint::Create("sha-1",
142 &info->certificate->ssl_certificate()));
143 EXPECT_TRUE(fp);
144 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
145 // Fingerprints of the rest of the chain.
146 std::unique_ptr<rtc::SSLCertChain> chain =
147 info->certificate->ssl_certificate().GetChain();
148 if (chain) {
149 for (size_t i = 0; i < chain->GetSize(); i++) {
150 fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain->Get(i)));
151 EXPECT_TRUE(fp);
152 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
153 }
154 }
155 EXPECT_EQ(info->ders.size(), info->fingerprints.size());
156 return info;
157}
158
hbosab9f6e42016-10-07 02:18:47 -0700159std::unique_ptr<cricket::Candidate> CreateFakeCandidate(
160 const std::string& hostname,
161 int port,
162 const std::string& protocol,
163 const std::string& candidate_type,
164 uint32_t priority) {
165 std::unique_ptr<cricket::Candidate> candidate(new cricket::Candidate());
166 candidate->set_address(rtc::SocketAddress(hostname, port));
167 candidate->set_protocol(protocol);
168 candidate->set_type(candidate_type);
169 candidate->set_priority(priority);
170 return candidate;
171}
172
hbos09bc1282016-11-08 06:29:22 -0800173class FakeAudioTrackForStats
174 : public MediaStreamTrack<AudioTrackInterface> {
175 public:
176 static rtc::scoped_refptr<FakeAudioTrackForStats> Create(
177 const std::string& id,
hbos9e302742017-01-20 02:47:10 -0800178 MediaStreamTrackInterface::TrackState state) {
hbos09bc1282016-11-08 06:29:22 -0800179 rtc::scoped_refptr<FakeAudioTrackForStats> audio_track_stats(
hbos9e302742017-01-20 02:47:10 -0800180 new rtc::RefCountedObject<FakeAudioTrackForStats>(id));
hbos09bc1282016-11-08 06:29:22 -0800181 audio_track_stats->set_state(state);
182 return audio_track_stats;
183 }
184
Steve Anton36b29d12017-10-30 09:57:42 -0700185 explicit FakeAudioTrackForStats(const std::string& id)
186 : MediaStreamTrack<AudioTrackInterface>(id) {}
hbos09bc1282016-11-08 06:29:22 -0800187
188 std::string kind() const override {
189 return MediaStreamTrackInterface::kAudioKind;
190 }
191 webrtc::AudioSourceInterface* GetSource() const override { return nullptr; }
192 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
193 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
hbos9e302742017-01-20 02:47:10 -0800194 bool GetSignalLevel(int* level) override { return false; }
hbos09bc1282016-11-08 06:29:22 -0800195 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
hbos9e302742017-01-20 02:47:10 -0800196 return nullptr;
hbos09bc1282016-11-08 06:29:22 -0800197 }
hbos09bc1282016-11-08 06:29:22 -0800198};
199
200class FakeVideoTrackForStats
201 : public MediaStreamTrack<VideoTrackInterface> {
202 public:
203 static rtc::scoped_refptr<FakeVideoTrackForStats> Create(
204 const std::string& id,
hbos9e302742017-01-20 02:47:10 -0800205 MediaStreamTrackInterface::TrackState state) {
hbos09bc1282016-11-08 06:29:22 -0800206 rtc::scoped_refptr<FakeVideoTrackForStats> video_track(
hbos9e302742017-01-20 02:47:10 -0800207 new rtc::RefCountedObject<FakeVideoTrackForStats>(id));
hbos09bc1282016-11-08 06:29:22 -0800208 video_track->set_state(state);
209 return video_track;
210 }
211
Steve Anton36b29d12017-10-30 09:57:42 -0700212 explicit FakeVideoTrackForStats(const std::string& id)
213 : MediaStreamTrack<VideoTrackInterface>(id) {}
hbos09bc1282016-11-08 06:29:22 -0800214
215 std::string kind() const override {
216 return MediaStreamTrackInterface::kVideoKind;
217 }
perkj773be362017-07-31 23:22:01 -0700218
219 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
220 const rtc::VideoSinkWants& wants) override{};
221 void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override{};
222
hbos9e302742017-01-20 02:47:10 -0800223 VideoTrackSourceInterface* GetSource() const override { return nullptr; }
hbos09bc1282016-11-08 06:29:22 -0800224};
225
hbos84abeb12017-01-16 06:16:44 -0800226rtc::scoped_refptr<MediaStreamTrackInterface> CreateFakeTrack(
227 cricket::MediaType media_type,
hbos9e302742017-01-20 02:47:10 -0800228 const std::string& track_id,
229 MediaStreamTrackInterface::TrackState track_state) {
hbos84abeb12017-01-16 06:16:44 -0800230 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800231 return FakeAudioTrackForStats::Create(track_id, track_state);
hbos84abeb12017-01-16 06:16:44 -0800232 } else {
233 RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
hbos9e302742017-01-20 02:47:10 -0800234 return FakeVideoTrackForStats::Create(track_id, track_state);
hbos84abeb12017-01-16 06:16:44 -0800235 }
236}
237
hbos9e302742017-01-20 02:47:10 -0800238rtc::scoped_refptr<MockRtpSender> CreateMockSender(
239 rtc::scoped_refptr<MediaStreamTrackInterface> track, uint32_t ssrc) {
240 rtc::scoped_refptr<MockRtpSender> sender(
241 new rtc::RefCountedObject<MockRtpSender>());
242 EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
243 EXPECT_CALL(*sender, ssrc()).WillRepeatedly(Return(ssrc));
244 EXPECT_CALL(*sender, media_type()).WillRepeatedly(Return(
245 track->kind() == MediaStreamTrackInterface::kAudioKind
246 ? cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO));
247 EXPECT_CALL(*sender, GetParameters()).WillRepeatedly(Invoke(
248 [ssrc]() {
249 RtpParameters params;
250 params.encodings.push_back(RtpEncodingParameters());
251 params.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
252 return params;
253 }));
254 return sender;
255}
256
257rtc::scoped_refptr<MockRtpReceiver> CreateMockReceiver(
258 rtc::scoped_refptr<MediaStreamTrackInterface> track, uint32_t ssrc) {
259 rtc::scoped_refptr<MockRtpReceiver> receiver(
260 new rtc::RefCountedObject<MockRtpReceiver>());
261 EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
262 EXPECT_CALL(*receiver, media_type()).WillRepeatedly(Return(
263 track->kind() == MediaStreamTrackInterface::kAudioKind
264 ? cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO));
265 EXPECT_CALL(*receiver, GetParameters()).WillRepeatedly(Invoke(
266 [ssrc]() {
267 RtpParameters params;
268 params.encodings.push_back(RtpEncodingParameters());
269 params.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
270 return params;
271 }));
272 return receiver;
273}
274
hbosc82f2e12016-09-05 01:36:50 -0700275class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
hbosd565b732016-08-30 14:04:35 -0700276 public:
hbosc82f2e12016-09-05 01:36:50 -0700277 RTCStatsCollectorTestHelper()
hbosd565b732016-08-30 14:04:35 -0700278 : worker_thread_(rtc::Thread::Current()),
279 network_thread_(rtc::Thread::Current()),
deadbeefbad5dad2017-01-17 18:32:35 -0800280 signaling_thread_(rtc::Thread::Current()),
hbos6ded1902016-11-01 01:50:46 -0700281 media_engine_(new cricket::FakeMediaEngine()),
deadbeef112b2e92017-02-10 20:13:37 -0800282 channel_manager_(new cricket::ChannelManager(
283 std::unique_ptr<cricket::MediaEngineInterface>(media_engine_),
284 worker_thread_,
285 network_thread_)),
nisseeaabdf62017-05-05 02:23:02 -0700286 session_(channel_manager_.get(), cricket::MediaConfig()),
hbosd565b732016-08-30 14:04:35 -0700287 pc_() {
Steve Anton978b8762017-09-29 12:15:02 -0700288 pc_.set_session_for_testing(&session_);
hbos6ab97ce2016-10-03 14:16:56 -0700289 // Default return values for mocks.
hbos09bc1282016-11-08 06:29:22 -0800290 EXPECT_CALL(pc_, local_streams()).WillRepeatedly(Return(nullptr));
291 EXPECT_CALL(pc_, remote_streams()).WillRepeatedly(Return(nullptr));
hbos84abeb12017-01-16 06:16:44 -0800292 EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
293 std::vector<rtc::scoped_refptr<RtpSenderInterface>>()));
294 EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
295 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>()));
hbosd565b732016-08-30 14:04:35 -0700296 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly(
297 ReturnRef(data_channels_));
hbos6ded1902016-11-01 01:50:46 -0700298 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
299 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
hbosdf6075a2016-12-19 04:58:02 -0800300 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
hbosab9f6e42016-10-07 02:18:47 -0700301 EXPECT_CALL(session_, GetLocalCertificate(_, _)).WillRepeatedly(
302 Return(false));
303 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
304 .WillRepeatedly(Return(nullptr));
hbosd565b732016-08-30 14:04:35 -0700305 }
306
hbosfdafab82016-09-14 06:02:13 -0700307 rtc::ScopedFakeClock& fake_clock() { return fake_clock_; }
hbos6ded1902016-11-01 01:50:46 -0700308 rtc::Thread* worker_thread() { return worker_thread_; }
309 rtc::Thread* network_thread() { return network_thread_; }
deadbeefbad5dad2017-01-17 18:32:35 -0800310 rtc::Thread* signaling_thread() { return signaling_thread_; }
hbos6ded1902016-11-01 01:50:46 -0700311 cricket::FakeMediaEngine* media_engine() { return media_engine_; }
hbosd565b732016-08-30 14:04:35 -0700312 MockWebRtcSession& session() { return session_; }
313 MockPeerConnection& pc() { return pc_; }
314 std::vector<rtc::scoped_refptr<DataChannel>>& data_channels() {
315 return data_channels_;
316 }
317
318 // SetSessionDescriptionObserver overrides.
319 void OnSuccess() override {}
320 void OnFailure(const std::string& error) override {
321 RTC_NOTREACHED() << error;
322 }
323
hbos84abeb12017-01-16 06:16:44 -0800324 void SetupLocalTrackAndSender(cricket::MediaType media_type,
325 const std::string& track_id,
326 uint32_t ssrc) {
327 rtc::scoped_refptr<StreamCollection> local_streams =
328 StreamCollection::Create();
329 EXPECT_CALL(pc_, local_streams())
330 .WillRepeatedly(Return(local_streams));
331
332 rtc::scoped_refptr<MediaStream> local_stream =
333 MediaStream::Create("LocalStreamLabel");
334 local_streams->AddStream(local_stream);
335
336 rtc::scoped_refptr<MediaStreamTrackInterface> track;
337 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800338 track = CreateFakeTrack(media_type, track_id,
339 MediaStreamTrackInterface::kLive);
hbos84abeb12017-01-16 06:16:44 -0800340 local_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
341 } else {
hbos9e302742017-01-20 02:47:10 -0800342 track = CreateFakeTrack(media_type, track_id,
343 MediaStreamTrackInterface::kLive);
hbos84abeb12017-01-16 06:16:44 -0800344 local_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
345 }
346
hbos9e302742017-01-20 02:47:10 -0800347 rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, ssrc);
hbos84abeb12017-01-16 06:16:44 -0800348 EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
349 std::vector<rtc::scoped_refptr<RtpSenderInterface>>({
350 rtc::scoped_refptr<RtpSenderInterface>(sender.get()) })));
351 }
352
353 void SetupRemoteTrackAndReceiver(cricket::MediaType media_type,
354 const std::string& track_id,
355 uint32_t ssrc) {
356 rtc::scoped_refptr<StreamCollection> remote_streams =
357 StreamCollection::Create();
358 EXPECT_CALL(pc_, remote_streams())
359 .WillRepeatedly(Return(remote_streams));
360
361 rtc::scoped_refptr<MediaStream> remote_stream =
362 MediaStream::Create("RemoteStreamLabel");
363 remote_streams->AddStream(remote_stream);
364
365 rtc::scoped_refptr<MediaStreamTrackInterface> track;
366 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800367 track = CreateFakeTrack(media_type, track_id,
368 MediaStreamTrackInterface::kLive);
hbos84abeb12017-01-16 06:16:44 -0800369 remote_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
370 } else {
hbos9e302742017-01-20 02:47:10 -0800371 track = CreateFakeTrack(media_type, track_id,
372 MediaStreamTrackInterface::kLive);
hbos84abeb12017-01-16 06:16:44 -0800373 remote_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
374 }
375
hbos9e302742017-01-20 02:47:10 -0800376 rtc::scoped_refptr<MockRtpReceiver> receiver =
377 CreateMockReceiver(track, ssrc);
hbos84abeb12017-01-16 06:16:44 -0800378 EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
379 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>({
380 rtc::scoped_refptr<RtpReceiverInterface>(receiver.get()) })));
381 }
382
hbos9e302742017-01-20 02:47:10 -0800383 // Attaches tracks to peer connections by configuring RTP senders and RTP
384 // receivers according to the tracks' pairings with
385 // |[Voice/Video][Sender/Receiver]Info| and their SSRCs. Local tracks can be
386 // associated with multiple |[Voice/Video]SenderInfo|s, remote tracks can only
387 // be associated with one |[Voice/Video]ReceiverInfo|.
388 void CreateMockRtpSendersReceiversAndChannels(
389 std::initializer_list<std::pair<MediaStreamTrackInterface*,
390 cricket::VoiceSenderInfo>> local_audio_track_info_pairs,
391 std::initializer_list<std::pair<MediaStreamTrackInterface*,
392 cricket::VoiceReceiverInfo>> remote_audio_track_info_pairs,
393 std::initializer_list<std::pair<MediaStreamTrackInterface*,
394 cricket::VideoSenderInfo>> local_video_track_info_pairs,
395 std::initializer_list<std::pair<MediaStreamTrackInterface*,
396 cricket::VideoReceiverInfo>> remote_video_track_info_pairs) {
397 voice_media_info_.reset(new cricket::VoiceMediaInfo());
398 video_media_info_.reset(new cricket::VideoMediaInfo());
399 rtp_senders_.clear();
400 rtp_receivers_.clear();
401 // Local audio tracks and voice sender infos
402 for (auto& pair : local_audio_track_info_pairs) {
403 MediaStreamTrackInterface* local_audio_track = pair.first;
404 const cricket::VoiceSenderInfo& voice_sender_info = pair.second;
405 RTC_DCHECK_EQ(local_audio_track->kind(),
406 MediaStreamTrackInterface::kAudioKind);
407
408 voice_media_info_->senders.push_back(voice_sender_info);
409 rtc::scoped_refptr<MockRtpSender> rtp_sender =
410 CreateMockSender(rtc::scoped_refptr<MediaStreamTrackInterface>(
411 local_audio_track),
412 voice_sender_info.local_stats[0].ssrc);
413 rtp_senders_.push_back(rtc::scoped_refptr<RtpSenderInterface>(
414 rtp_sender.get()));
415 }
416 // Remote audio tracks and voice receiver infos
417 for (auto& pair : remote_audio_track_info_pairs) {
418 MediaStreamTrackInterface* remote_audio_track = pair.first;
419 const cricket::VoiceReceiverInfo& voice_receiver_info = pair.second;
420 RTC_DCHECK_EQ(remote_audio_track->kind(),
421 MediaStreamTrackInterface::kAudioKind);
422
423 voice_media_info_->receivers.push_back(voice_receiver_info);
424 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver =
425 CreateMockReceiver(rtc::scoped_refptr<MediaStreamTrackInterface>(
426 remote_audio_track),
427 voice_receiver_info.local_stats[0].ssrc);
428 rtp_receivers_.push_back(rtc::scoped_refptr<RtpReceiverInterface>(
429 rtp_receiver.get()));
430 }
431 // Local video tracks and video sender infos
432 for (auto& pair : local_video_track_info_pairs) {
433 MediaStreamTrackInterface* local_video_track = pair.first;
434 const cricket::VideoSenderInfo& video_sender_info = pair.second;
435 RTC_DCHECK_EQ(local_video_track->kind(),
436 MediaStreamTrackInterface::kVideoKind);
437
438 video_media_info_->senders.push_back(video_sender_info);
439 rtc::scoped_refptr<MockRtpSender> rtp_sender =
440 CreateMockSender(rtc::scoped_refptr<MediaStreamTrackInterface>(
441 local_video_track),
442 video_sender_info.local_stats[0].ssrc);
443 rtp_senders_.push_back(rtc::scoped_refptr<RtpSenderInterface>(
444 rtp_sender.get()));
445 }
446 // Remote video tracks and video receiver infos
447 for (auto& pair : remote_video_track_info_pairs) {
448 MediaStreamTrackInterface* remote_video_track = pair.first;
449 const cricket::VideoReceiverInfo& video_receiver_info = pair.second;
450 RTC_DCHECK_EQ(remote_video_track->kind(),
451 MediaStreamTrackInterface::kVideoKind);
452
453 video_media_info_->receivers.push_back(video_receiver_info);
454 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver =
455 CreateMockReceiver(rtc::scoped_refptr<MediaStreamTrackInterface>(
456 remote_video_track),
457 video_receiver_info.local_stats[0].ssrc);
458 rtp_receivers_.push_back(rtc::scoped_refptr<RtpReceiverInterface>(
459 rtp_receiver.get()));
460 }
461 EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(rtp_senders_));
462 EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(rtp_receivers_));
463
464 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
465 voice_channel_.reset(new cricket::VoiceChannel(
466 worker_thread_, network_thread_, nullptr, media_engine_,
467 voice_media_channel, "VoiceContentName", kDefaultRtcpMuxRequired,
468 kDefaultSrtpRequired));
469 EXPECT_CALL(session_, voice_channel())
470 .WillRepeatedly(Return(voice_channel_.get()));
471 EXPECT_CALL(*voice_media_channel, GetStats(_))
472 .WillOnce(DoAll(SetArgPointee<0>(*voice_media_info_), Return(true)));
473
474 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
475 video_channel_.reset(new cricket::VideoChannel(
476 worker_thread_, network_thread_, nullptr, video_media_channel,
477 "VideoContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired));
478 EXPECT_CALL(session_, video_channel())
479 .WillRepeatedly(Return(video_channel_.get()));
480 EXPECT_CALL(*video_media_channel, GetStats(_))
481 .WillOnce(DoAll(SetArgPointee<0>(*video_media_info_), Return(true)));
482 }
483
hbosd565b732016-08-30 14:04:35 -0700484 private:
hbosfdafab82016-09-14 06:02:13 -0700485 rtc::ScopedFakeClock fake_clock_;
hbos09bc1282016-11-08 06:29:22 -0800486 RtcEventLogNullImpl event_log_;
hbosd565b732016-08-30 14:04:35 -0700487 rtc::Thread* const worker_thread_;
488 rtc::Thread* const network_thread_;
deadbeefbad5dad2017-01-17 18:32:35 -0800489 rtc::Thread* const signaling_thread_;
deadbeef112b2e92017-02-10 20:13:37 -0800490 // |media_engine_| is actually owned by |channel_manager_|.
hbos6ded1902016-11-01 01:50:46 -0700491 cricket::FakeMediaEngine* media_engine_;
hbosd565b732016-08-30 14:04:35 -0700492 std::unique_ptr<cricket::ChannelManager> channel_manager_;
hbosd565b732016-08-30 14:04:35 -0700493 MockWebRtcSession session_;
494 MockPeerConnection pc_;
495
496 std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
hbos9e302742017-01-20 02:47:10 -0800497 std::unique_ptr<cricket::VoiceChannel> voice_channel_;
498 std::unique_ptr<cricket::VideoChannel> video_channel_;
499 std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info_;
500 std::unique_ptr<cricket::VideoMediaInfo> video_media_info_;
501 std::vector<rtc::scoped_refptr<RtpSenderInterface>> rtp_senders_;
502 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> rtp_receivers_;
hbosd565b732016-08-30 14:04:35 -0700503};
504
hbosc82f2e12016-09-05 01:36:50 -0700505class RTCTestStats : public RTCStats {
hbosd565b732016-08-30 14:04:35 -0700506 public:
hbosfc5e0502016-10-06 02:06:10 -0700507 WEBRTC_RTCSTATS_DECL();
508
hbosc82f2e12016-09-05 01:36:50 -0700509 RTCTestStats(const std::string& id, int64_t timestamp_us)
510 : RTCStats(id, timestamp_us),
511 dummy_stat("dummyStat") {}
512
hbosc82f2e12016-09-05 01:36:50 -0700513 RTCStatsMember<int32_t> dummy_stat;
514};
515
hbosfc5e0502016-10-06 02:06:10 -0700516WEBRTC_RTCSTATS_IMPL(RTCTestStats, RTCStats, "test-stats",
517 &dummy_stat);
hbosc82f2e12016-09-05 01:36:50 -0700518
519// Overrides the stats collection to verify thread usage and that the resulting
520// partial reports are merged.
521class FakeRTCStatsCollector : public RTCStatsCollector,
522 public RTCStatsCollectorCallback {
523 public:
524 static rtc::scoped_refptr<FakeRTCStatsCollector> Create(
525 PeerConnection* pc,
526 int64_t cache_lifetime_us) {
527 return rtc::scoped_refptr<FakeRTCStatsCollector>(
528 new rtc::RefCountedObject<FakeRTCStatsCollector>(
529 pc, cache_lifetime_us));
530 }
531
532 // RTCStatsCollectorCallback implementation.
533 void OnStatsDelivered(
534 const rtc::scoped_refptr<const RTCStatsReport>& report) override {
535 EXPECT_TRUE(signaling_thread_->IsCurrent());
536 rtc::CritScope cs(&lock_);
537 delivered_report_ = report;
538 }
539
540 void VerifyThreadUsageAndResultsMerging() {
541 GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback>(this));
542 EXPECT_TRUE_WAIT(HasVerifiedResults(), kGetStatsReportTimeoutMs);
543 }
544
545 bool HasVerifiedResults() {
546 EXPECT_TRUE(signaling_thread_->IsCurrent());
547 rtc::CritScope cs(&lock_);
548 if (!delivered_report_)
549 return false;
550 EXPECT_EQ(produced_on_signaling_thread_, 1);
hbosc82f2e12016-09-05 01:36:50 -0700551 EXPECT_EQ(produced_on_network_thread_, 1);
552
553 EXPECT_TRUE(delivered_report_->Get("SignalingThreadStats"));
hbosc82f2e12016-09-05 01:36:50 -0700554 EXPECT_TRUE(delivered_report_->Get("NetworkThreadStats"));
555
556 produced_on_signaling_thread_ = 0;
hbosc82f2e12016-09-05 01:36:50 -0700557 produced_on_network_thread_ = 0;
558 delivered_report_ = nullptr;
559 return true;
hbosd565b732016-08-30 14:04:35 -0700560 }
561
562 protected:
Steve Anton978b8762017-09-29 12:15:02 -0700563 FakeRTCStatsCollector(PeerConnection* pc, int64_t cache_lifetime)
hbosc82f2e12016-09-05 01:36:50 -0700564 : RTCStatsCollector(pc, cache_lifetime),
Steve Anton978b8762017-09-29 12:15:02 -0700565 signaling_thread_(pc->signaling_thread()),
566 worker_thread_(pc->worker_thread()),
567 network_thread_(pc->network_thread()) {}
hbosc82f2e12016-09-05 01:36:50 -0700568
569 void ProducePartialResultsOnSignalingThread(int64_t timestamp_us) override {
570 EXPECT_TRUE(signaling_thread_->IsCurrent());
571 {
572 rtc::CritScope cs(&lock_);
573 EXPECT_FALSE(delivered_report_);
574 ++produced_on_signaling_thread_;
575 }
576
577 rtc::scoped_refptr<RTCStatsReport> signaling_report =
hbos6ded1902016-11-01 01:50:46 -0700578 RTCStatsReport::Create(0);
hbosc82f2e12016-09-05 01:36:50 -0700579 signaling_report->AddStats(std::unique_ptr<const RTCStats>(
580 new RTCTestStats("SignalingThreadStats", timestamp_us)));
581 AddPartialResults(signaling_report);
582 }
hbosc82f2e12016-09-05 01:36:50 -0700583 void ProducePartialResultsOnNetworkThread(int64_t timestamp_us) override {
584 EXPECT_TRUE(network_thread_->IsCurrent());
585 {
586 rtc::CritScope cs(&lock_);
587 EXPECT_FALSE(delivered_report_);
588 ++produced_on_network_thread_;
589 }
590
591 rtc::scoped_refptr<RTCStatsReport> network_report =
hbos6ded1902016-11-01 01:50:46 -0700592 RTCStatsReport::Create(0);
hbosc82f2e12016-09-05 01:36:50 -0700593 network_report->AddStats(std::unique_ptr<const RTCStats>(
594 new RTCTestStats("NetworkThreadStats", timestamp_us)));
595 AddPartialResults(network_report);
596 }
597
598 private:
599 rtc::Thread* const signaling_thread_;
600 rtc::Thread* const worker_thread_;
601 rtc::Thread* const network_thread_;
602
603 rtc::CriticalSection lock_;
604 rtc::scoped_refptr<const RTCStatsReport> delivered_report_;
605 int produced_on_signaling_thread_ = 0;
hbosc82f2e12016-09-05 01:36:50 -0700606 int produced_on_network_thread_ = 0;
hbosd565b732016-08-30 14:04:35 -0700607};
608
hbosc82f2e12016-09-05 01:36:50 -0700609class RTCStatsCollectorTest : public testing::Test {
610 public:
611 RTCStatsCollectorTest()
612 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()),
613 collector_(RTCStatsCollector::Create(
614 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) {
615 }
616
617 rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() {
hbosdb346a72016-11-29 01:57:01 -0800618 rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
hbosc82f2e12016-09-05 01:36:50 -0700619 collector_->GetStatsReport(callback);
620 EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs);
hboscc555c52016-10-18 12:48:31 -0700621 int64_t after = rtc::TimeUTCMicros();
622 for (const RTCStats& stats : *callback->report()) {
623 EXPECT_LE(stats.timestamp_us(), after);
624 }
hbosc82f2e12016-09-05 01:36:50 -0700625 return callback->report();
626 }
627
hbos6ab97ce2016-10-03 14:16:56 -0700628 void ExpectReportContainsCertificateInfo(
629 const rtc::scoped_refptr<const RTCStatsReport>& report,
hbos23368e12016-12-21 04:29:17 -0800630 const CertificateInfo& certinfo) {
631 for (size_t i = 0; i < certinfo.fingerprints.size(); ++i) {
632 RTCCertificateStats expected_certificate_stats(
633 "RTCCertificate_" + certinfo.fingerprints[i],
634 report->timestamp_us());
635 expected_certificate_stats.fingerprint = certinfo.fingerprints[i];
636 expected_certificate_stats.fingerprint_algorithm = "sha-1";
637 expected_certificate_stats.base64_certificate = certinfo.pems[i];
638 if (i + 1 < certinfo.fingerprints.size()) {
639 expected_certificate_stats.issuer_certificate_id =
640 "RTCCertificate_" + certinfo.fingerprints[i + 1];
hbos6ab97ce2016-10-03 14:16:56 -0700641 }
hbos23368e12016-12-21 04:29:17 -0800642 ASSERT_TRUE(report->Get(expected_certificate_stats.id()));
643 EXPECT_EQ(expected_certificate_stats,
644 report->Get(expected_certificate_stats.id())->cast_to<
645 RTCCertificateStats>());
hbos6ab97ce2016-10-03 14:16:56 -0700646 }
647 }
648
hbosc82f2e12016-09-05 01:36:50 -0700649 protected:
650 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_;
651 rtc::scoped_refptr<RTCStatsCollector> collector_;
652};
653
654TEST_F(RTCStatsCollectorTest, SingleCallback) {
655 rtc::scoped_refptr<const RTCStatsReport> result;
hbosdb346a72016-11-29 01:57:01 -0800656 collector_->GetStatsReport(RTCStatsObtainer::Create(&result));
hbosc82f2e12016-09-05 01:36:50 -0700657 EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs);
658}
659
660TEST_F(RTCStatsCollectorTest, MultipleCallbacks) {
661 rtc::scoped_refptr<const RTCStatsReport> a;
662 rtc::scoped_refptr<const RTCStatsReport> b;
663 rtc::scoped_refptr<const RTCStatsReport> c;
hbosdb346a72016-11-29 01:57:01 -0800664 collector_->GetStatsReport(RTCStatsObtainer::Create(&a));
665 collector_->GetStatsReport(RTCStatsObtainer::Create(&b));
666 collector_->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 01:36:50 -0700667 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
668 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
669 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
670 EXPECT_EQ(a.get(), b.get());
671 EXPECT_EQ(b.get(), c.get());
672}
673
674TEST_F(RTCStatsCollectorTest, CachedStatsReports) {
hbosd565b732016-08-30 14:04:35 -0700675 // Caching should ensure |a| and |b| are the same report.
hbosc82f2e12016-09-05 01:36:50 -0700676 rtc::scoped_refptr<const RTCStatsReport> a = GetStatsReport();
677 rtc::scoped_refptr<const RTCStatsReport> b = GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700678 EXPECT_EQ(a.get(), b.get());
679 // Invalidate cache by clearing it.
hbosc82f2e12016-09-05 01:36:50 -0700680 collector_->ClearCachedStatsReport();
681 rtc::scoped_refptr<const RTCStatsReport> c = GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700682 EXPECT_NE(b.get(), c.get());
683 // Invalidate cache by advancing time.
hbosfdafab82016-09-14 06:02:13 -0700684 test_->fake_clock().AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
hbosc82f2e12016-09-05 01:36:50 -0700685 rtc::scoped_refptr<const RTCStatsReport> d = GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700686 EXPECT_TRUE(d);
687 EXPECT_NE(c.get(), d.get());
688}
689
hbosc82f2e12016-09-05 01:36:50 -0700690TEST_F(RTCStatsCollectorTest, MultipleCallbacksWithInvalidatedCacheInBetween) {
hbosc82f2e12016-09-05 01:36:50 -0700691 rtc::scoped_refptr<const RTCStatsReport> a;
692 rtc::scoped_refptr<const RTCStatsReport> b;
693 rtc::scoped_refptr<const RTCStatsReport> c;
hbosdb346a72016-11-29 01:57:01 -0800694 collector_->GetStatsReport(RTCStatsObtainer::Create(&a));
695 collector_->GetStatsReport(RTCStatsObtainer::Create(&b));
hbosc82f2e12016-09-05 01:36:50 -0700696 // Cache is invalidated after 50 ms.
hbosfdafab82016-09-14 06:02:13 -0700697 test_->fake_clock().AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
hbosdb346a72016-11-29 01:57:01 -0800698 collector_->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 01:36:50 -0700699 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
700 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
701 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
702 EXPECT_EQ(a.get(), b.get());
703 // The act of doing |AdvanceTime| processes all messages. If this was not the
704 // case we might not require |c| to be fresher than |b|.
705 EXPECT_NE(c.get(), b.get());
706}
707
hbos6ab97ce2016-10-03 14:16:56 -0700708TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) {
709 std::unique_ptr<CertificateInfo> local_certinfo =
710 CreateFakeCertificateAndInfoFromDers(
711 std::vector<std::string>({ "(local) single certificate" }));
712 std::unique_ptr<CertificateInfo> remote_certinfo =
713 CreateFakeCertificateAndInfoFromDers(
714 std::vector<std::string>({ "(remote) single certificate" }));
715
716 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 04:58:02 -0800717 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700718 [](const ChannelNamePairs&) {
hbosdf6075a2016-12-19 04:58:02 -0800719 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce2016-10-03 14:16:56 -0700720 stats->transport_stats["transport"].transport_name = "transport";
hbosdf6075a2016-12-19 04:58:02 -0800721 return stats;
hbos6ab97ce2016-10-03 14:16:56 -0700722 }));
723 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
eladalon1cc5fc32017-08-23 04:15:18 -0700724 Invoke([&local_certinfo](const std::string& transport_name,
hbos6ab97ce2016-10-03 14:16:56 -0700725 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
726 if (transport_name == "transport") {
727 *certificate = local_certinfo->certificate;
728 return true;
729 }
730 return false;
731 }));
732 EXPECT_CALL(test_->session(),
733 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700734 [&remote_certinfo](const std::string& transport_name) {
hbos6ab97ce2016-10-03 14:16:56 -0700735 if (transport_name == "transport")
736 return remote_certinfo->certificate->ssl_certificate().GetReference();
737 return static_cast<rtc::SSLCertificate*>(nullptr);
738 }));
739
740 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos23368e12016-12-21 04:29:17 -0800741 ExpectReportContainsCertificateInfo(report, *local_certinfo);
742 ExpectReportContainsCertificateInfo(report, *remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700743}
744
hbos0adb8282016-11-23 02:32:06 -0800745TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
746 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
747 cricket::VoiceChannel voice_channel(
deadbeefbad5dad2017-01-17 18:32:35 -0800748 test_->worker_thread(), test_->network_thread(),
749 test_->signaling_thread(), test_->media_engine(), voice_media_channel,
750 "VoiceContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hbos0adb8282016-11-23 02:32:06 -0800751
752 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
753 cricket::VideoChannel video_channel(
deadbeefbad5dad2017-01-17 18:32:35 -0800754 test_->worker_thread(), test_->network_thread(),
755 test_->signaling_thread(), video_media_channel, "VideoContentName",
756 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hbos0adb8282016-11-23 02:32:06 -0800757
758 // Audio
759 cricket::VoiceMediaInfo voice_media_info;
760
761 RtpCodecParameters inbound_audio_codec;
762 inbound_audio_codec.payload_type = 1;
deadbeefe702b302017-02-04 12:09:01 -0800763 inbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
764 inbound_audio_codec.name = "opus";
765 inbound_audio_codec.clock_rate = rtc::Optional<int>(1337);
hbos0adb8282016-11-23 02:32:06 -0800766 voice_media_info.receive_codecs.insert(
767 std::make_pair(inbound_audio_codec.payload_type, inbound_audio_codec));
768
769 RtpCodecParameters outbound_audio_codec;
770 outbound_audio_codec.payload_type = 2;
deadbeefe702b302017-02-04 12:09:01 -0800771 outbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
772 outbound_audio_codec.name = "isac";
773 outbound_audio_codec.clock_rate = rtc::Optional<int>(1338);
hbos0adb8282016-11-23 02:32:06 -0800774 voice_media_info.send_codecs.insert(
775 std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
776
777 EXPECT_CALL(*voice_media_channel, GetStats(_))
778 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
779
780 // Video
781 cricket::VideoMediaInfo video_media_info;
782
783 RtpCodecParameters inbound_video_codec;
784 inbound_video_codec.payload_type = 3;
deadbeefe702b302017-02-04 12:09:01 -0800785 inbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
786 inbound_video_codec.name = "H264";
787 inbound_video_codec.clock_rate = rtc::Optional<int>(1339);
hbos0adb8282016-11-23 02:32:06 -0800788 video_media_info.receive_codecs.insert(
789 std::make_pair(inbound_video_codec.payload_type, inbound_video_codec));
790
791 RtpCodecParameters outbound_video_codec;
792 outbound_video_codec.payload_type = 4;
deadbeefe702b302017-02-04 12:09:01 -0800793 outbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
794 outbound_video_codec.name = "VP8";
795 outbound_video_codec.clock_rate = rtc::Optional<int>(1340);
hbos0adb8282016-11-23 02:32:06 -0800796 video_media_info.send_codecs.insert(
797 std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
798
799 EXPECT_CALL(*video_media_channel, GetStats(_))
800 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
801
802 SessionStats session_stats;
803 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
804 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
805 session_stats.transport_stats["TransportName"].transport_name =
806 "TransportName";
807
hbosdf6075a2016-12-19 04:58:02 -0800808 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
809 [&session_stats](const ChannelNamePairs&) {
810 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
811 }));
hbos0adb8282016-11-23 02:32:06 -0800812 EXPECT_CALL(test_->session(), voice_channel())
813 .WillRepeatedly(Return(&voice_channel));
814 EXPECT_CALL(test_->session(), video_channel())
815 .WillRepeatedly(Return(&video_channel));
816
817 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
818
819 RTCCodecStats expected_inbound_audio_codec(
820 "RTCCodec_InboundAudio_1", report->timestamp_us());
821 expected_inbound_audio_codec.payload_type = 1;
hbos13f54b22017-02-28 06:56:04 -0800822 expected_inbound_audio_codec.mime_type = "audio/opus";
hbos0adb8282016-11-23 02:32:06 -0800823 expected_inbound_audio_codec.clock_rate = 1337;
824
825 RTCCodecStats expected_outbound_audio_codec(
826 "RTCCodec_OutboundAudio_2", report->timestamp_us());
827 expected_outbound_audio_codec.payload_type = 2;
hbos13f54b22017-02-28 06:56:04 -0800828 expected_outbound_audio_codec.mime_type = "audio/isac";
hbos0adb8282016-11-23 02:32:06 -0800829 expected_outbound_audio_codec.clock_rate = 1338;
830
831 RTCCodecStats expected_inbound_video_codec(
832 "RTCCodec_InboundVideo_3", report->timestamp_us());
833 expected_inbound_video_codec.payload_type = 3;
hbos13f54b22017-02-28 06:56:04 -0800834 expected_inbound_video_codec.mime_type = "video/H264";
hbos0adb8282016-11-23 02:32:06 -0800835 expected_inbound_video_codec.clock_rate = 1339;
836
837 RTCCodecStats expected_outbound_video_codec(
838 "RTCCodec_OutboundVideo_4", report->timestamp_us());
839 expected_outbound_video_codec.payload_type = 4;
hbos13f54b22017-02-28 06:56:04 -0800840 expected_outbound_video_codec.mime_type = "video/VP8";
hbos0adb8282016-11-23 02:32:06 -0800841 expected_outbound_video_codec.clock_rate = 1340;
842
nissec8ee8822017-01-18 07:20:55 -0800843 ASSERT_TRUE(report->Get(expected_inbound_audio_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800844 EXPECT_EQ(expected_inbound_audio_codec,
845 report->Get(expected_inbound_audio_codec.id())->cast_to<
846 RTCCodecStats>());
847
nissec8ee8822017-01-18 07:20:55 -0800848 ASSERT_TRUE(report->Get(expected_outbound_audio_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800849 EXPECT_EQ(expected_outbound_audio_codec,
850 report->Get(expected_outbound_audio_codec.id())->cast_to<
851 RTCCodecStats>());
852
nissec8ee8822017-01-18 07:20:55 -0800853 ASSERT_TRUE(report->Get(expected_inbound_video_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800854 EXPECT_EQ(expected_inbound_video_codec,
855 report->Get(expected_inbound_video_codec.id())->cast_to<
856 RTCCodecStats>());
857
nissec8ee8822017-01-18 07:20:55 -0800858 ASSERT_TRUE(report->Get(expected_outbound_video_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800859 EXPECT_EQ(expected_outbound_video_codec,
860 report->Get(expected_outbound_video_codec.id())->cast_to<
861 RTCCodecStats>());
862}
863
hbos6ab97ce2016-10-03 14:16:56 -0700864TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
865 std::unique_ptr<CertificateInfo> audio_local_certinfo =
866 CreateFakeCertificateAndInfoFromDers(
867 std::vector<std::string>({ "(local) audio" }));
868 audio_local_certinfo = CreateFakeCertificateAndInfoFromDers(
869 audio_local_certinfo->ders);
870 std::unique_ptr<CertificateInfo> audio_remote_certinfo =
871 CreateFakeCertificateAndInfoFromDers(
872 std::vector<std::string>({ "(remote) audio" }));
873 audio_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
874 audio_remote_certinfo->ders);
875
876 std::unique_ptr<CertificateInfo> video_local_certinfo =
877 CreateFakeCertificateAndInfoFromDers(
878 std::vector<std::string>({ "(local) video" }));
879 video_local_certinfo = CreateFakeCertificateAndInfoFromDers(
880 video_local_certinfo->ders);
881 std::unique_ptr<CertificateInfo> video_remote_certinfo =
882 CreateFakeCertificateAndInfoFromDers(
883 std::vector<std::string>({ "(remote) video" }));
884 video_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
885 video_remote_certinfo->ders);
886
887 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 04:58:02 -0800888 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700889 [](const ChannelNamePairs&) {
hbosdf6075a2016-12-19 04:58:02 -0800890 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce2016-10-03 14:16:56 -0700891 stats->transport_stats["audio"].transport_name = "audio";
892 stats->transport_stats["video"].transport_name = "video";
hbosdf6075a2016-12-19 04:58:02 -0800893 return stats;
hbos6ab97ce2016-10-03 14:16:56 -0700894 }));
895 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
eladalon1cc5fc32017-08-23 04:15:18 -0700896 Invoke([&audio_local_certinfo, &video_local_certinfo](
hbos6ab97ce2016-10-03 14:16:56 -0700897 const std::string& transport_name,
898 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
899 if (transport_name == "audio") {
900 *certificate = audio_local_certinfo->certificate;
901 return true;
902 }
903 if (transport_name == "video") {
904 *certificate = video_local_certinfo->certificate;
905 return true;
906 }
907 return false;
908 }));
909 EXPECT_CALL(test_->session(),
910 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700911 [&audio_remote_certinfo, &video_remote_certinfo](
hbos6ab97ce2016-10-03 14:16:56 -0700912 const std::string& transport_name) {
913 if (transport_name == "audio") {
914 return audio_remote_certinfo->certificate->ssl_certificate()
915 .GetReference();
916 }
917 if (transport_name == "video") {
918 return video_remote_certinfo->certificate->ssl_certificate()
919 .GetReference();
920 }
921 return static_cast<rtc::SSLCertificate*>(nullptr);
922 }));
923
924 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos23368e12016-12-21 04:29:17 -0800925 ExpectReportContainsCertificateInfo(report, *audio_local_certinfo);
926 ExpectReportContainsCertificateInfo(report, *audio_remote_certinfo);
927 ExpectReportContainsCertificateInfo(report, *video_local_certinfo);
928 ExpectReportContainsCertificateInfo(report, *video_remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700929}
930
931TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
932 std::vector<std::string> local_ders;
933 local_ders.push_back("(local) this");
934 local_ders.push_back("(local) is");
935 local_ders.push_back("(local) a");
936 local_ders.push_back("(local) chain");
937 std::unique_ptr<CertificateInfo> local_certinfo =
938 CreateFakeCertificateAndInfoFromDers(local_ders);
939 std::vector<std::string> remote_ders;
940 remote_ders.push_back("(remote) this");
941 remote_ders.push_back("(remote) is");
942 remote_ders.push_back("(remote) another");
943 remote_ders.push_back("(remote) chain");
944 std::unique_ptr<CertificateInfo> remote_certinfo =
945 CreateFakeCertificateAndInfoFromDers(remote_ders);
946
947 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 04:58:02 -0800948 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700949 [](const ChannelNamePairs&) {
hbosdf6075a2016-12-19 04:58:02 -0800950 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce2016-10-03 14:16:56 -0700951 stats->transport_stats["transport"].transport_name = "transport";
hbosdf6075a2016-12-19 04:58:02 -0800952 return stats;
hbos6ab97ce2016-10-03 14:16:56 -0700953 }));
954 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
eladalon1cc5fc32017-08-23 04:15:18 -0700955 Invoke([&local_certinfo](const std::string& transport_name,
hbos6ab97ce2016-10-03 14:16:56 -0700956 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
957 if (transport_name == "transport") {
958 *certificate = local_certinfo->certificate;
959 return true;
960 }
961 return false;
962 }));
963 EXPECT_CALL(test_->session(),
964 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -0700965 [&remote_certinfo](const std::string& transport_name) {
hbos6ab97ce2016-10-03 14:16:56 -0700966 if (transport_name == "transport")
967 return remote_certinfo->certificate->ssl_certificate().GetReference();
968 return static_cast<rtc::SSLCertificate*>(nullptr);
969 }));
970
971 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos23368e12016-12-21 04:29:17 -0800972 ExpectReportContainsCertificateInfo(report, *local_certinfo);
973 ExpectReportContainsCertificateInfo(report, *remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700974}
975
hboscc555c52016-10-18 12:48:31 -0700976TEST_F(RTCStatsCollectorTest, CollectRTCDataChannelStats) {
977 test_->data_channels().push_back(
hbosdbb64d82016-12-21 01:57:46 -0800978 new MockDataChannel(
979 0, "MockDataChannel0", DataChannelInterface::kConnecting, "udp",
980 1, 2, 3, 4));
981 RTCDataChannelStats expected_data_channel0("RTCDataChannel_0", 0);
982 expected_data_channel0.label = "MockDataChannel0";
983 expected_data_channel0.protocol = "udp";
984 expected_data_channel0.datachannelid = 0;
985 expected_data_channel0.state = "connecting";
986 expected_data_channel0.messages_sent = 1;
987 expected_data_channel0.bytes_sent = 2;
988 expected_data_channel0.messages_received = 3;
989 expected_data_channel0.bytes_received = 4;
990
hboscc555c52016-10-18 12:48:31 -0700991 test_->data_channels().push_back(
hbosdbb64d82016-12-21 01:57:46 -0800992 new MockDataChannel(
993 1, "MockDataChannel1", DataChannelInterface::kOpen, "tcp",
994 5, 6, 7, 8));
995 RTCDataChannelStats expected_data_channel1("RTCDataChannel_1", 0);
996 expected_data_channel1.label = "MockDataChannel1";
997 expected_data_channel1.protocol = "tcp";
998 expected_data_channel1.datachannelid = 1;
999 expected_data_channel1.state = "open";
1000 expected_data_channel1.messages_sent = 5;
1001 expected_data_channel1.bytes_sent = 6;
1002 expected_data_channel1.messages_received = 7;
1003 expected_data_channel1.bytes_received = 8;
1004
hboscc555c52016-10-18 12:48:31 -07001005 test_->data_channels().push_back(
hbosdbb64d82016-12-21 01:57:46 -08001006 new MockDataChannel(
1007 2, "MockDataChannel2", DataChannelInterface::kClosing, "udp",
1008 9, 10, 11, 12));
1009 RTCDataChannelStats expected_data_channel2("RTCDataChannel_2", 0);
1010 expected_data_channel2.label = "MockDataChannel2";
1011 expected_data_channel2.protocol = "udp";
1012 expected_data_channel2.datachannelid = 2;
1013 expected_data_channel2.state = "closing";
1014 expected_data_channel2.messages_sent = 9;
1015 expected_data_channel2.bytes_sent = 10;
1016 expected_data_channel2.messages_received = 11;
1017 expected_data_channel2.bytes_received = 12;
1018
hboscc555c52016-10-18 12:48:31 -07001019 test_->data_channels().push_back(
hbosdbb64d82016-12-21 01:57:46 -08001020 new MockDataChannel(
1021 3, "MockDataChannel3", DataChannelInterface::kClosed, "tcp",
1022 13, 14, 15, 16));
1023 RTCDataChannelStats expected_data_channel3("RTCDataChannel_3", 0);
1024 expected_data_channel3.label = "MockDataChannel3";
1025 expected_data_channel3.protocol = "tcp";
1026 expected_data_channel3.datachannelid = 3;
1027 expected_data_channel3.state = "closed";
1028 expected_data_channel3.messages_sent = 13;
1029 expected_data_channel3.bytes_sent = 14;
1030 expected_data_channel3.messages_received = 15;
1031 expected_data_channel3.bytes_received = 16;
hboscc555c52016-10-18 12:48:31 -07001032
1033 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbosdbb64d82016-12-21 01:57:46 -08001034 ASSERT_TRUE(report->Get(expected_data_channel0.id()));
1035 EXPECT_EQ(expected_data_channel0,
1036 report->Get(expected_data_channel0.id())->cast_to<
1037 RTCDataChannelStats>());
1038 ASSERT_TRUE(report->Get(expected_data_channel1.id()));
1039 EXPECT_EQ(expected_data_channel1,
1040 report->Get(expected_data_channel1.id())->cast_to<
1041 RTCDataChannelStats>());
1042 ASSERT_TRUE(report->Get(expected_data_channel2.id()));
1043 EXPECT_EQ(expected_data_channel2,
1044 report->Get(expected_data_channel2.id())->cast_to<
1045 RTCDataChannelStats>());
1046 ASSERT_TRUE(report->Get(expected_data_channel3.id()));
1047 EXPECT_EQ(expected_data_channel3,
1048 report->Get(expected_data_channel3.id())->cast_to<
1049 RTCDataChannelStats>());
hboscc555c52016-10-18 12:48:31 -07001050}
1051
hbosab9f6e42016-10-07 02:18:47 -07001052TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
1053 // Candidates in the first transport stats.
1054 std::unique_ptr<cricket::Candidate> a_local_host = CreateFakeCandidate(
1055 "1.2.3.4", 5,
1056 "a_local_host's protocol",
1057 cricket::LOCAL_PORT_TYPE,
1058 0);
hbosc42ba322016-12-21 03:31:45 -08001059 RTCLocalIceCandidateStats expected_a_local_host(
1060 "RTCIceCandidate_" + a_local_host->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001061 expected_a_local_host.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -08001062 expected_a_local_host.ip = "1.2.3.4";
1063 expected_a_local_host.port = 5;
1064 expected_a_local_host.protocol = "a_local_host's protocol";
1065 expected_a_local_host.candidate_type = "host";
1066 expected_a_local_host.priority = 0;
hbosc3a2b7f2017-01-02 04:46:15 -08001067 EXPECT_FALSE(*expected_a_local_host.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001068
hbosab9f6e42016-10-07 02:18:47 -07001069 std::unique_ptr<cricket::Candidate> a_remote_srflx = CreateFakeCandidate(
1070 "6.7.8.9", 10,
1071 "remote_srflx's protocol",
1072 cricket::STUN_PORT_TYPE,
1073 1);
hbosc42ba322016-12-21 03:31:45 -08001074 RTCRemoteIceCandidateStats expected_a_remote_srflx(
1075 "RTCIceCandidate_" + a_remote_srflx->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001076 expected_a_remote_srflx.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -08001077 expected_a_remote_srflx.ip = "6.7.8.9";
1078 expected_a_remote_srflx.port = 10;
1079 expected_a_remote_srflx.protocol = "remote_srflx's protocol";
1080 expected_a_remote_srflx.candidate_type = "srflx";
1081 expected_a_remote_srflx.priority = 1;
hbosd17a5a72017-01-02 08:09:59 -08001082 expected_a_remote_srflx.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001083 EXPECT_TRUE(*expected_a_remote_srflx.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001084
hbosab9f6e42016-10-07 02:18:47 -07001085 std::unique_ptr<cricket::Candidate> a_local_prflx = CreateFakeCandidate(
1086 "11.12.13.14", 15,
1087 "a_local_prflx's protocol",
1088 cricket::PRFLX_PORT_TYPE,
1089 2);
hbosc42ba322016-12-21 03:31:45 -08001090 RTCLocalIceCandidateStats expected_a_local_prflx(
1091 "RTCIceCandidate_" + a_local_prflx->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001092 expected_a_local_prflx.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -08001093 expected_a_local_prflx.ip = "11.12.13.14";
1094 expected_a_local_prflx.port = 15;
1095 expected_a_local_prflx.protocol = "a_local_prflx's protocol";
1096 expected_a_local_prflx.candidate_type = "prflx";
1097 expected_a_local_prflx.priority = 2;
hbosd17a5a72017-01-02 08:09:59 -08001098 expected_a_local_prflx.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001099 EXPECT_FALSE(*expected_a_local_prflx.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001100
hbosab9f6e42016-10-07 02:18:47 -07001101 std::unique_ptr<cricket::Candidate> a_remote_relay = CreateFakeCandidate(
1102 "16.17.18.19", 20,
1103 "a_remote_relay's protocol",
1104 cricket::RELAY_PORT_TYPE,
1105 3);
hbosc42ba322016-12-21 03:31:45 -08001106 RTCRemoteIceCandidateStats expected_a_remote_relay(
1107 "RTCIceCandidate_" + a_remote_relay->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001108 expected_a_remote_relay.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -08001109 expected_a_remote_relay.ip = "16.17.18.19";
1110 expected_a_remote_relay.port = 20;
1111 expected_a_remote_relay.protocol = "a_remote_relay's protocol";
1112 expected_a_remote_relay.candidate_type = "relay";
1113 expected_a_remote_relay.priority = 3;
hbosd17a5a72017-01-02 08:09:59 -08001114 expected_a_remote_relay.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001115 EXPECT_TRUE(*expected_a_remote_relay.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001116
hbosab9f6e42016-10-07 02:18:47 -07001117 // Candidates in the second transport stats.
1118 std::unique_ptr<cricket::Candidate> b_local = CreateFakeCandidate(
1119 "42.42.42.42", 42,
1120 "b_local's protocol",
1121 cricket::LOCAL_PORT_TYPE,
1122 42);
hbosc42ba322016-12-21 03:31:45 -08001123 RTCLocalIceCandidateStats expected_b_local(
1124 "RTCIceCandidate_" + b_local->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001125 expected_b_local.transport_id = "RTCTransport_b_0";
hbosc42ba322016-12-21 03:31:45 -08001126 expected_b_local.ip = "42.42.42.42";
1127 expected_b_local.port = 42;
1128 expected_b_local.protocol = "b_local's protocol";
1129 expected_b_local.candidate_type = "host";
1130 expected_b_local.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001131 expected_b_local.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001132 EXPECT_FALSE(*expected_b_local.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001133
hbosab9f6e42016-10-07 02:18:47 -07001134 std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
1135 "42.42.42.42", 42,
1136 "b_remote's protocol",
1137 cricket::LOCAL_PORT_TYPE,
1138 42);
hbosc42ba322016-12-21 03:31:45 -08001139 RTCRemoteIceCandidateStats expected_b_remote(
1140 "RTCIceCandidate_" + b_remote->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -08001141 expected_b_remote.transport_id = "RTCTransport_b_0";
hbosc42ba322016-12-21 03:31:45 -08001142 expected_b_remote.ip = "42.42.42.42";
1143 expected_b_remote.port = 42;
1144 expected_b_remote.protocol = "b_remote's protocol";
1145 expected_b_remote.candidate_type = "host";
1146 expected_b_remote.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001147 expected_b_remote.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001148 EXPECT_TRUE(*expected_b_remote.is_remote);
hbosab9f6e42016-10-07 02:18:47 -07001149
1150 SessionStats session_stats;
1151
1152 cricket::TransportChannelStats a_transport_channel_stats;
1153 a_transport_channel_stats.connection_infos.push_back(
1154 cricket::ConnectionInfo());
1155 a_transport_channel_stats.connection_infos[0].local_candidate =
1156 *a_local_host.get();
1157 a_transport_channel_stats.connection_infos[0].remote_candidate =
1158 *a_remote_srflx.get();
1159 a_transport_channel_stats.connection_infos.push_back(
1160 cricket::ConnectionInfo());
1161 a_transport_channel_stats.connection_infos[1].local_candidate =
1162 *a_local_prflx.get();
1163 a_transport_channel_stats.connection_infos[1].remote_candidate =
1164 *a_remote_relay.get();
hbos02d2a922016-12-21 01:29:05 -08001165 session_stats.transport_stats["a"].transport_name = "a";
hbosab9f6e42016-10-07 02:18:47 -07001166 session_stats.transport_stats["a"].channel_stats.push_back(
1167 a_transport_channel_stats);
1168
1169 cricket::TransportChannelStats b_transport_channel_stats;
1170 b_transport_channel_stats.connection_infos.push_back(
1171 cricket::ConnectionInfo());
1172 b_transport_channel_stats.connection_infos[0].local_candidate =
1173 *b_local.get();
1174 b_transport_channel_stats.connection_infos[0].remote_candidate =
1175 *b_remote.get();
hbos02d2a922016-12-21 01:29:05 -08001176 session_stats.transport_stats["b"].transport_name = "b";
hbosab9f6e42016-10-07 02:18:47 -07001177 session_stats.transport_stats["b"].channel_stats.push_back(
1178 b_transport_channel_stats);
1179
1180 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 04:58:02 -08001181 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1182 [&session_stats](const ChannelNamePairs&) {
1183 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbosab9f6e42016-10-07 02:18:47 -07001184 }));
1185
1186 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbosc42ba322016-12-21 03:31:45 -08001187
hbosb4e426e2017-01-02 09:59:31 -08001188 ASSERT_TRUE(report->Get(expected_a_local_host.id()));
hbosc42ba322016-12-21 03:31:45 -08001189 EXPECT_EQ(expected_a_local_host,
1190 report->Get(expected_a_local_host.id())->cast_to<
1191 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001192 ASSERT_TRUE(report->Get(expected_a_remote_srflx.id()));
hbosc42ba322016-12-21 03:31:45 -08001193 EXPECT_EQ(expected_a_remote_srflx,
1194 report->Get(expected_a_remote_srflx.id())->cast_to<
1195 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001196 ASSERT_TRUE(report->Get(expected_a_local_prflx.id()));
hbosc42ba322016-12-21 03:31:45 -08001197 EXPECT_EQ(expected_a_local_prflx,
1198 report->Get(expected_a_local_prflx.id())->cast_to<
1199 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001200 ASSERT_TRUE(report->Get(expected_a_remote_relay.id()));
hbosc42ba322016-12-21 03:31:45 -08001201 EXPECT_EQ(expected_a_remote_relay,
1202 report->Get(expected_a_remote_relay.id())->cast_to<
1203 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001204 ASSERT_TRUE(report->Get(expected_b_local.id()));
hbosc42ba322016-12-21 03:31:45 -08001205 EXPECT_EQ(expected_b_local,
1206 report->Get(expected_b_local.id())->cast_to<
1207 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001208 ASSERT_TRUE(report->Get(expected_b_remote.id()));
hbosc42ba322016-12-21 03:31:45 -08001209 EXPECT_EQ(expected_b_remote,
1210 report->Get(expected_b_remote.id())->cast_to<
1211 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -08001212 EXPECT_TRUE(report->Get("RTCTransport_a_0"));
1213 EXPECT_TRUE(report->Get("RTCTransport_b_0"));
hbosab9f6e42016-10-07 02:18:47 -07001214}
1215
hbosc47a0c32016-10-11 14:54:49 -07001216TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
hbos338f78a2017-02-07 06:41:21 -08001217 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
1218 cricket::VideoChannel video_channel(
1219 test_->worker_thread(), test_->network_thread(),
1220 test_->signaling_thread(), video_media_channel, "VideoContentName",
1221 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
1222
hbosc47a0c32016-10-11 14:54:49 -07001223 std::unique_ptr<cricket::Candidate> local_candidate = CreateFakeCandidate(
1224 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
1225 std::unique_ptr<cricket::Candidate> remote_candidate = CreateFakeCandidate(
1226 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
1227
1228 SessionStats session_stats;
1229
1230 cricket::ConnectionInfo connection_info;
hbos338f78a2017-02-07 06:41:21 -08001231 connection_info.best_connection = false;
hbosc47a0c32016-10-11 14:54:49 -07001232 connection_info.local_candidate = *local_candidate.get();
1233 connection_info.remote_candidate = *remote_candidate.get();
1234 connection_info.writable = true;
1235 connection_info.sent_total_bytes = 42;
1236 connection_info.recv_total_bytes = 1234;
hbosbf8d3e52017-02-28 06:34:47 -08001237 connection_info.total_round_trip_time_ms = 0;
1238 connection_info.current_round_trip_time_ms = rtc::Optional<uint32_t>();
hbosd82f5122016-12-09 04:12:39 -08001239 connection_info.recv_ping_requests = 2020;
hbose448dd52016-12-12 01:22:53 -08001240 connection_info.sent_ping_requests_total = 2020;
1241 connection_info.sent_ping_requests_before_first_response = 2000;
hbosc47a0c32016-10-11 14:54:49 -07001242 connection_info.recv_ping_responses = 4321;
1243 connection_info.sent_ping_responses = 1000;
hbos06495bc2017-01-02 08:08:18 -08001244 connection_info.state = cricket::IceCandidatePairState::IN_PROGRESS;
1245 connection_info.priority = 5555;
hbos92eaec62017-02-27 01:38:08 -08001246 connection_info.nominated = false;
hbosc47a0c32016-10-11 14:54:49 -07001247
1248 cricket::TransportChannelStats transport_channel_stats;
hbos0583b282016-11-30 01:50:14 -08001249 transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbosc47a0c32016-10-11 14:54:49 -07001250 transport_channel_stats.connection_infos.push_back(connection_info);
hbos338f78a2017-02-07 06:41:21 -08001251 session_stats.proxy_to_transport["VideoContentName"] = "transport";
hbosc47a0c32016-10-11 14:54:49 -07001252 session_stats.transport_stats["transport"].transport_name = "transport";
1253 session_stats.transport_stats["transport"].channel_stats.push_back(
1254 transport_channel_stats);
1255
1256 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 04:58:02 -08001257 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1258 [&session_stats](const ChannelNamePairs&) {
1259 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbosc47a0c32016-10-11 14:54:49 -07001260 }));
1261
hbos338f78a2017-02-07 06:41:21 -08001262 // Mock the session to return bandwidth estimation info. These should only
1263 // be used for a selected candidate pair.
1264 cricket::VideoMediaInfo video_media_info;
hbos338f78a2017-02-07 06:41:21 -08001265 EXPECT_CALL(*video_media_channel, GetStats(_))
1266 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1267 EXPECT_CALL(test_->session(), video_channel())
1268 .WillRepeatedly(Return(&video_channel));
1269
hbosc47a0c32016-10-11 14:54:49 -07001270 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08001271
1272 RTCIceCandidatePairStats expected_pair("RTCIceCandidatePair_" +
1273 local_candidate->id() + "_" +
1274 remote_candidate->id(),
1275 report->timestamp_us());
1276 expected_pair.transport_id =
1277 "RTCTransport_transport_" +
1278 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1279 expected_pair.local_candidate_id = "RTCIceCandidate_" + local_candidate->id();
1280 expected_pair.remote_candidate_id =
1281 "RTCIceCandidate_" + remote_candidate->id();
hbos06495bc2017-01-02 08:08:18 -08001282 expected_pair.state = RTCStatsIceCandidatePairState::kInProgress;
1283 expected_pair.priority = 5555;
hbos92eaec62017-02-27 01:38:08 -08001284 expected_pair.nominated = false;
hbos0583b282016-11-30 01:50:14 -08001285 expected_pair.writable = true;
1286 expected_pair.bytes_sent = 42;
1287 expected_pair.bytes_received = 1234;
hbosbf8d3e52017-02-28 06:34:47 -08001288 expected_pair.total_round_trip_time = 0.0;
hbosd82f5122016-12-09 04:12:39 -08001289 expected_pair.requests_received = 2020;
hbose448dd52016-12-12 01:22:53 -08001290 expected_pair.requests_sent = 2000;
hbos0583b282016-11-30 01:50:14 -08001291 expected_pair.responses_received = 4321;
1292 expected_pair.responses_sent = 1000;
hbose448dd52016-12-12 01:22:53 -08001293 expected_pair.consent_requests_sent = (2020 - 2000);
hbosbf8d3e52017-02-28 06:34:47 -08001294 // |expected_pair.current_round_trip_time| should be undefined because the
1295 // current RTT is not set.
hbos338f78a2017-02-07 06:41:21 -08001296 // |expected_pair.available_[outgoing/incoming]_bitrate| should be undefined
1297 // because is is not the current pair.
hbos0583b282016-11-30 01:50:14 -08001298
hbosdbb64d82016-12-21 01:57:46 -08001299 ASSERT_TRUE(report->Get(expected_pair.id()));
hbos0583b282016-11-30 01:50:14 -08001300 EXPECT_EQ(
1301 expected_pair,
1302 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
hbosb4e426e2017-01-02 09:59:31 -08001303 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
hbos0583b282016-11-30 01:50:14 -08001304
hbos92eaec62017-02-27 01:38:08 -08001305 // Set nominated and "GetStats" again.
1306 session_stats.transport_stats["transport"]
1307 .channel_stats[0]
1308 .connection_infos[0]
1309 .nominated = true;
1310 EXPECT_CALL(*video_media_channel, GetStats(_))
1311 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1312 collector_->ClearCachedStatsReport();
1313 report = GetStatsReport();
1314 expected_pair.nominated = true;
1315 ASSERT_TRUE(report->Get(expected_pair.id()));
1316 EXPECT_EQ(
1317 expected_pair,
1318 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1319 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1320
hbosbf8d3e52017-02-28 06:34:47 -08001321 // Set round trip times and "GetStats" again.
1322 session_stats.transport_stats["transport"].channel_stats[0]
1323 .connection_infos[0].total_round_trip_time_ms = 7331;
1324 session_stats.transport_stats["transport"].channel_stats[0]
1325 .connection_infos[0].current_round_trip_time_ms =
1326 rtc::Optional<uint32_t>(1337);
1327 EXPECT_CALL(*video_media_channel, GetStats(_))
1328 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1329 collector_->ClearCachedStatsReport();
1330 report = GetStatsReport();
1331 expected_pair.total_round_trip_time = 7.331;
1332 expected_pair.current_round_trip_time = 1.337;
1333 ASSERT_TRUE(report->Get(expected_pair.id()));
1334 EXPECT_EQ(
1335 expected_pair,
1336 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1337 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1338
hbos338f78a2017-02-07 06:41:21 -08001339 // Make pair the current pair, clear bandwidth and "GetStats" again.
1340 session_stats.transport_stats["transport"]
1341 .channel_stats[0]
1342 .connection_infos[0]
1343 .best_connection = true;
hbos338f78a2017-02-07 06:41:21 -08001344 EXPECT_CALL(*video_media_channel, GetStats(_))
1345 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1346 collector_->ClearCachedStatsReport();
1347 report = GetStatsReport();
1348 // |expected_pair.available_[outgoing/incoming]_bitrate| should still be
1349 // undefined because bandwidth is not set.
1350 ASSERT_TRUE(report->Get(expected_pair.id()));
1351 EXPECT_EQ(
1352 expected_pair,
1353 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1354 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1355
1356 // Set bandwidth and "GetStats" again.
stefanf79ade12017-06-02 06:44:03 -07001357 webrtc::Call::Stats call_stats;
1358 const int kSendBandwidth = 888;
1359 call_stats.send_bandwidth_bps = kSendBandwidth;
1360 const int kRecvBandwidth = 999;
1361 call_stats.recv_bandwidth_bps = kRecvBandwidth;
1362 EXPECT_CALL(test_->session(), GetCallStats())
1363 .WillRepeatedly(Return(call_stats));
hbos338f78a2017-02-07 06:41:21 -08001364 EXPECT_CALL(*video_media_channel, GetStats(_))
1365 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1366 collector_->ClearCachedStatsReport();
1367 report = GetStatsReport();
stefanf79ade12017-06-02 06:44:03 -07001368 expected_pair.available_outgoing_bitrate = kSendBandwidth;
1369 expected_pair.available_incoming_bitrate = kRecvBandwidth;
hbos338f78a2017-02-07 06:41:21 -08001370 ASSERT_TRUE(report->Get(expected_pair.id()));
1371 EXPECT_EQ(
1372 expected_pair,
1373 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1374 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1375
hbosc42ba322016-12-21 03:31:45 -08001376 RTCLocalIceCandidateStats expected_local_candidate(
1377 *expected_pair.local_candidate_id, report->timestamp_us());
hbosb4e426e2017-01-02 09:59:31 -08001378 expected_local_candidate.transport_id = *expected_pair.transport_id;
hbosc42ba322016-12-21 03:31:45 -08001379 expected_local_candidate.ip = "42.42.42.42";
1380 expected_local_candidate.port = 42;
1381 expected_local_candidate.protocol = "protocol";
1382 expected_local_candidate.candidate_type = "host";
1383 expected_local_candidate.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001384 expected_local_candidate.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001385 EXPECT_FALSE(*expected_local_candidate.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001386 ASSERT_TRUE(report->Get(expected_local_candidate.id()));
1387 EXPECT_EQ(expected_local_candidate,
1388 report->Get(expected_local_candidate.id())->cast_to<
1389 RTCLocalIceCandidateStats>());
1390
1391 RTCRemoteIceCandidateStats expected_remote_candidate(
1392 *expected_pair.remote_candidate_id, report->timestamp_us());
hbosb4e426e2017-01-02 09:59:31 -08001393 expected_remote_candidate.transport_id = *expected_pair.transport_id;
hbosc42ba322016-12-21 03:31:45 -08001394 expected_remote_candidate.ip = "42.42.42.42";
1395 expected_remote_candidate.port = 42;
1396 expected_remote_candidate.protocol = "protocol";
1397 expected_remote_candidate.candidate_type = "host";
1398 expected_remote_candidate.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001399 expected_remote_candidate.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001400 EXPECT_TRUE(*expected_remote_candidate.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001401 ASSERT_TRUE(report->Get(expected_remote_candidate.id()));
1402 EXPECT_EQ(expected_remote_candidate,
1403 report->Get(expected_remote_candidate.id())->cast_to<
1404 RTCRemoteIceCandidateStats>());
hbosc47a0c32016-10-11 14:54:49 -07001405}
1406
hbosd565b732016-08-30 14:04:35 -07001407TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
hbosd565b732016-08-30 14:04:35 -07001408 {
hbos82ebe022016-11-14 01:41:09 -08001409 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1410 RTCPeerConnectionStats expected("RTCPeerConnection",
1411 report->timestamp_us());
1412 expected.data_channels_opened = 0;
1413 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 01:57:46 -08001414 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001415 EXPECT_EQ(expected,
1416 report->Get("RTCPeerConnection")->cast_to<
1417 RTCPeerConnectionStats>());
hbosd565b732016-08-30 14:04:35 -07001418 }
1419
hbos82ebe022016-11-14 01:41:09 -08001420 rtc::scoped_refptr<DataChannel> dummy_channel_a = DataChannel::Create(
1421 nullptr, cricket::DCT_NONE, "DummyChannelA", InternalDataChannelInit());
1422 test_->pc().SignalDataChannelCreated(dummy_channel_a.get());
1423 rtc::scoped_refptr<DataChannel> dummy_channel_b = DataChannel::Create(
1424 nullptr, cricket::DCT_NONE, "DummyChannelB", InternalDataChannelInit());
1425 test_->pc().SignalDataChannelCreated(dummy_channel_b.get());
hbosd565b732016-08-30 14:04:35 -07001426
hbos82ebe022016-11-14 01:41:09 -08001427 dummy_channel_a->SignalOpened(dummy_channel_a.get());
1428 // Closing a channel that is not opened should not affect the counts.
1429 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1430
hbosd565b732016-08-30 14:04:35 -07001431 {
hbos82ebe022016-11-14 01:41:09 -08001432 collector_->ClearCachedStatsReport();
1433 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1434 RTCPeerConnectionStats expected("RTCPeerConnection",
1435 report->timestamp_us());
1436 expected.data_channels_opened = 1;
1437 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 01:57:46 -08001438 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001439 EXPECT_EQ(expected,
1440 report->Get("RTCPeerConnection")->cast_to<
1441 RTCPeerConnectionStats>());
1442 }
1443
1444 dummy_channel_b->SignalOpened(dummy_channel_b.get());
1445 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1446
1447 {
1448 collector_->ClearCachedStatsReport();
1449 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1450 RTCPeerConnectionStats expected("RTCPeerConnection",
1451 report->timestamp_us());
1452 expected.data_channels_opened = 2;
1453 expected.data_channels_closed = 1;
hbosdbb64d82016-12-21 01:57:46 -08001454 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001455 EXPECT_EQ(expected,
1456 report->Get("RTCPeerConnection")->cast_to<
1457 RTCPeerConnectionStats>());
hbosd565b732016-08-30 14:04:35 -07001458 }
hbos5bf9def2017-03-20 03:14:14 -07001459
1460 // Re-opening a data channel (or opening a new data channel that is re-using
1461 // the same address in memory) should increase the opened count.
1462 dummy_channel_b->SignalOpened(dummy_channel_b.get());
1463
1464 {
1465 collector_->ClearCachedStatsReport();
1466 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1467 RTCPeerConnectionStats expected("RTCPeerConnection",
1468 report->timestamp_us());
1469 expected.data_channels_opened = 3;
1470 expected.data_channels_closed = 1;
1471 ASSERT_TRUE(report->Get("RTCPeerConnection"));
1472 EXPECT_EQ(expected,
1473 report->Get("RTCPeerConnection")->cast_to<
1474 RTCPeerConnectionStats>());
1475 }
1476
1477 dummy_channel_a->SignalClosed(dummy_channel_a.get());
1478 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1479
1480 {
1481 collector_->ClearCachedStatsReport();
1482 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1483 RTCPeerConnectionStats expected("RTCPeerConnection",
1484 report->timestamp_us());
1485 expected.data_channels_opened = 3;
1486 expected.data_channels_closed = 3;
1487 ASSERT_TRUE(report->Get("RTCPeerConnection"));
1488 EXPECT_EQ(expected,
1489 report->Get("RTCPeerConnection")->cast_to<
1490 RTCPeerConnectionStats>());
1491 }
hbosd565b732016-08-30 14:04:35 -07001492}
1493
hbos09bc1282016-11-08 06:29:22 -08001494TEST_F(RTCStatsCollectorTest,
1495 CollectRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
1496 rtc::scoped_refptr<StreamCollection> local_streams =
1497 StreamCollection::Create();
1498 rtc::scoped_refptr<StreamCollection> remote_streams =
1499 StreamCollection::Create();
1500 EXPECT_CALL(test_->pc(), local_streams())
1501 .WillRepeatedly(Return(local_streams));
1502 EXPECT_CALL(test_->pc(), remote_streams())
1503 .WillRepeatedly(Return(remote_streams));
1504
1505 rtc::scoped_refptr<MediaStream> local_stream =
1506 MediaStream::Create("LocalStreamLabel");
1507 local_streams->AddStream(local_stream);
1508 rtc::scoped_refptr<MediaStream> remote_stream =
1509 MediaStream::Create("RemoteStreamLabel");
1510 remote_streams->AddStream(remote_stream);
1511
1512 // Local audio track
hbos9e302742017-01-20 02:47:10 -08001513 rtc::scoped_refptr<MediaStreamTrackInterface> local_audio_track =
1514 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID",
1515 MediaStreamTrackInterface::kEnded);
1516 local_stream->AddTrack(static_cast<AudioTrackInterface*>(
1517 local_audio_track.get()));
1518
1519 cricket::VoiceSenderInfo voice_sender_info_ssrc1;
1520 voice_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
1521 voice_sender_info_ssrc1.local_stats[0].ssrc = 1;
1522 voice_sender_info_ssrc1.audio_level = 32767;
zsteine76bd3a2017-07-14 12:17:49 -07001523 voice_sender_info_ssrc1.total_input_energy = 0.25;
1524 voice_sender_info_ssrc1.total_input_duration = 0.5;
hbos9e302742017-01-20 02:47:10 -08001525 voice_sender_info_ssrc1.echo_return_loss = 42;
1526 voice_sender_info_ssrc1.echo_return_loss_enhancement = 52;
1527
1528 // Uses default values, the corresponding stats object should contain
1529 // undefined members.
1530 cricket::VoiceSenderInfo voice_sender_info_ssrc2;
1531 voice_sender_info_ssrc2.local_stats.push_back(cricket::SsrcSenderInfo());
1532 voice_sender_info_ssrc2.local_stats[0].ssrc = 2;
1533 voice_sender_info_ssrc2.audio_level = 0;
zsteine76bd3a2017-07-14 12:17:49 -07001534 voice_sender_info_ssrc2.total_input_energy = 0.0;
1535 voice_sender_info_ssrc2.total_input_duration = 0.0;
hbos9e302742017-01-20 02:47:10 -08001536 voice_sender_info_ssrc2.echo_return_loss = -100;
1537 voice_sender_info_ssrc2.echo_return_loss_enhancement = -100;
hbos09bc1282016-11-08 06:29:22 -08001538
1539 // Remote audio track
hbos9e302742017-01-20 02:47:10 -08001540 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio_track =
1541 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID",
1542 MediaStreamTrackInterface::kLive);
1543 remote_stream->AddTrack(static_cast<AudioTrackInterface*>(
1544 remote_audio_track.get()));
1545
1546 cricket::VoiceReceiverInfo voice_receiver_info;
1547 voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo());
1548 voice_receiver_info.local_stats[0].ssrc = 3;
1549 voice_receiver_info.audio_level = 16383;
zsteine76bd3a2017-07-14 12:17:49 -07001550 voice_receiver_info.total_output_energy = 0.125;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001551 voice_receiver_info.total_samples_received = 4567;
zsteine76bd3a2017-07-14 12:17:49 -07001552 voice_receiver_info.total_output_duration = 0.25;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001553 voice_receiver_info.concealed_samples = 123;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001554 voice_receiver_info.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02001555 voice_receiver_info.jitter_buffer_delay_seconds = 3456;
hbos9e302742017-01-20 02:47:10 -08001556
1557 test_->CreateMockRtpSendersReceiversAndChannels(
1558 { std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1),
1559 std::make_pair(local_audio_track.get(), voice_sender_info_ssrc2) },
1560 { std::make_pair(remote_audio_track.get(), voice_receiver_info) },
1561 {}, {});
hbos09bc1282016-11-08 06:29:22 -08001562
1563 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1564
1565 RTCMediaStreamStats expected_local_stream(
hbos02d2a922016-12-21 01:29:05 -08001566 "RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001567 expected_local_stream.stream_identifier = local_stream->label();
hbos9e302742017-01-20 02:47:10 -08001568 expected_local_stream.track_ids = std::vector<std::string>(
1569 { "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1",
1570 "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_2" });
hbosdbb64d82016-12-21 01:57:46 -08001571 ASSERT_TRUE(report->Get(expected_local_stream.id()));
hbos09bc1282016-11-08 06:29:22 -08001572 EXPECT_EQ(expected_local_stream,
1573 report->Get(expected_local_stream.id())->cast_to<
1574 RTCMediaStreamStats>());
1575
1576 RTCMediaStreamStats expected_remote_stream(
hbos02d2a922016-12-21 01:29:05 -08001577 "RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001578 expected_remote_stream.stream_identifier = remote_stream->label();
hbos9e302742017-01-20 02:47:10 -08001579 expected_remote_stream.track_ids = std::vector<std::string>({
1580 "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_3" });
hbosdbb64d82016-12-21 01:57:46 -08001581 ASSERT_TRUE(report->Get(expected_remote_stream.id()));
hbos09bc1282016-11-08 06:29:22 -08001582 EXPECT_EQ(expected_remote_stream,
1583 report->Get(expected_remote_stream.id())->cast_to<
1584 RTCMediaStreamStats>());
1585
hbos9e302742017-01-20 02:47:10 -08001586 RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
1587 "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1",
1588 report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
1589 expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
1590 expected_local_audio_track_ssrc1.remote_source = false;
1591 expected_local_audio_track_ssrc1.ended = true;
1592 expected_local_audio_track_ssrc1.detached = false;
1593 expected_local_audio_track_ssrc1.audio_level = 1.0;
zsteine76bd3a2017-07-14 12:17:49 -07001594 expected_local_audio_track_ssrc1.total_audio_energy = 0.25;
1595 expected_local_audio_track_ssrc1.total_samples_duration = 0.5;
hbos9e302742017-01-20 02:47:10 -08001596 expected_local_audio_track_ssrc1.echo_return_loss = 42.0;
1597 expected_local_audio_track_ssrc1.echo_return_loss_enhancement = 52.0;
1598 ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc1.id()));
1599 EXPECT_EQ(expected_local_audio_track_ssrc1,
1600 report->Get(expected_local_audio_track_ssrc1.id())->cast_to<
1601 RTCMediaStreamTrackStats>());
1602
1603 RTCMediaStreamTrackStats expected_local_audio_track_ssrc2(
1604 "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_2",
1605 report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
1606 expected_local_audio_track_ssrc2.track_identifier = local_audio_track->id();
1607 expected_local_audio_track_ssrc2.remote_source = false;
1608 expected_local_audio_track_ssrc2.ended = true;
1609 expected_local_audio_track_ssrc2.detached = false;
1610 expected_local_audio_track_ssrc2.audio_level = 0.0;
zsteine76bd3a2017-07-14 12:17:49 -07001611 expected_local_audio_track_ssrc2.total_audio_energy = 0.0;
1612 expected_local_audio_track_ssrc2.total_samples_duration = 0.0;
hbos9e302742017-01-20 02:47:10 -08001613 // Should be undefined: |expected_local_audio_track_ssrc2.echo_return_loss|
1614 // and |expected_local_audio_track_ssrc2.echo_return_loss_enhancement|.
1615 ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc2.id()));
1616 EXPECT_EQ(expected_local_audio_track_ssrc2,
1617 report->Get(expected_local_audio_track_ssrc2.id())->cast_to<
hbos09bc1282016-11-08 06:29:22 -08001618 RTCMediaStreamTrackStats>());
1619
1620 RTCMediaStreamTrackStats expected_remote_audio_track(
hbos9e302742017-01-20 02:47:10 -08001621 "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_3",
1622 report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
hbos09bc1282016-11-08 06:29:22 -08001623 expected_remote_audio_track.track_identifier = remote_audio_track->id();
1624 expected_remote_audio_track.remote_source = true;
1625 expected_remote_audio_track.ended = false;
1626 expected_remote_audio_track.detached = false;
hbos9e302742017-01-20 02:47:10 -08001627 expected_remote_audio_track.audio_level = 16383.0 / 32767.0;
zsteine76bd3a2017-07-14 12:17:49 -07001628 expected_remote_audio_track.total_audio_energy = 0.125;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001629 expected_remote_audio_track.total_samples_received = 4567;
zsteine76bd3a2017-07-14 12:17:49 -07001630 expected_remote_audio_track.total_samples_duration = 0.25;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001631 expected_remote_audio_track.concealed_samples = 123;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001632 expected_remote_audio_track.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02001633 expected_remote_audio_track.jitter_buffer_delay = 3456;
hbosdbb64d82016-12-21 01:57:46 -08001634 ASSERT_TRUE(report->Get(expected_remote_audio_track.id()));
hbos09bc1282016-11-08 06:29:22 -08001635 EXPECT_EQ(expected_remote_audio_track,
1636 report->Get(expected_remote_audio_track.id())->cast_to<
1637 RTCMediaStreamTrackStats>());
1638}
1639
1640TEST_F(RTCStatsCollectorTest,
1641 CollectRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
1642 rtc::scoped_refptr<StreamCollection> local_streams =
1643 StreamCollection::Create();
1644 rtc::scoped_refptr<StreamCollection> remote_streams =
1645 StreamCollection::Create();
1646 EXPECT_CALL(test_->pc(), local_streams())
1647 .WillRepeatedly(Return(local_streams));
1648 EXPECT_CALL(test_->pc(), remote_streams())
1649 .WillRepeatedly(Return(remote_streams));
1650
1651 rtc::scoped_refptr<MediaStream> local_stream =
1652 MediaStream::Create("LocalStreamLabel");
1653 local_streams->AddStream(local_stream);
1654 rtc::scoped_refptr<MediaStream> remote_stream =
1655 MediaStream::Create("RemoteStreamLabel");
1656 remote_streams->AddStream(remote_stream);
1657
1658 // Local video track
hbos9e302742017-01-20 02:47:10 -08001659 rtc::scoped_refptr<MediaStreamTrackInterface> local_video_track =
1660 CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID",
1661 MediaStreamTrackInterface::kLive);
1662 local_stream->AddTrack(static_cast<VideoTrackInterface*>(
1663 local_video_track.get()));
hbos09bc1282016-11-08 06:29:22 -08001664
hbos9e302742017-01-20 02:47:10 -08001665 cricket::VideoSenderInfo video_sender_info_ssrc1;
1666 video_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
1667 video_sender_info_ssrc1.local_stats[0].ssrc = 1;
1668 video_sender_info_ssrc1.send_frame_width = 1234;
1669 video_sender_info_ssrc1.send_frame_height = 4321;
hbosfefe0762017-01-20 06:14:25 -08001670 video_sender_info_ssrc1.frames_encoded = 11;
hbos9e302742017-01-20 02:47:10 -08001671
1672 cricket::VideoSenderInfo video_sender_info_ssrc2;
1673 video_sender_info_ssrc2.local_stats.push_back(cricket::SsrcSenderInfo());
1674 video_sender_info_ssrc2.local_stats[0].ssrc = 2;
1675 video_sender_info_ssrc2.send_frame_width = 4321;
1676 video_sender_info_ssrc2.send_frame_height = 1234;
hbosfefe0762017-01-20 06:14:25 -08001677 video_sender_info_ssrc2.frames_encoded = 22;
hbos9e302742017-01-20 02:47:10 -08001678
1679 // Remote video track with values
1680 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc3 =
1681 CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID3",
1682 MediaStreamTrackInterface::kEnded);
1683 remote_stream->AddTrack(static_cast<VideoTrackInterface*>(
1684 remote_video_track_ssrc3.get()));
1685
1686 cricket::VideoReceiverInfo video_receiver_info_ssrc3;
1687 video_receiver_info_ssrc3.local_stats.push_back(cricket::SsrcReceiverInfo());
1688 video_receiver_info_ssrc3.local_stats[0].ssrc = 3;
1689 video_receiver_info_ssrc3.frame_width = 6789;
1690 video_receiver_info_ssrc3.frame_height = 9876;
hbos50cfe1f2017-01-23 07:21:55 -08001691 video_receiver_info_ssrc3.frames_received = 1000;
1692 video_receiver_info_ssrc3.frames_decoded = 995;
1693 video_receiver_info_ssrc3.frames_rendered = 990;
hbos9e302742017-01-20 02:47:10 -08001694
1695 // Remote video track with undefined (default) values
1696 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc4 =
1697 CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID4",
1698 MediaStreamTrackInterface::kLive);
1699 remote_stream->AddTrack(static_cast<VideoTrackInterface*>(
1700 remote_video_track_ssrc4.get()));
1701
1702 cricket::VideoReceiverInfo video_receiver_info_ssrc4;
1703 video_receiver_info_ssrc4.local_stats.push_back(cricket::SsrcReceiverInfo());
1704 video_receiver_info_ssrc4.local_stats[0].ssrc = 4;
1705 video_receiver_info_ssrc4.frame_width = 0;
1706 video_receiver_info_ssrc4.frame_height = 0;
hbos42f6d2f2017-01-20 03:56:50 -08001707 video_receiver_info_ssrc4.frames_received = 0;
hbosf64941f2017-01-20 07:39:09 -08001708 video_receiver_info_ssrc4.frames_decoded = 0;
hbos50cfe1f2017-01-23 07:21:55 -08001709 video_receiver_info_ssrc4.frames_rendered = 0;
hbos9e302742017-01-20 02:47:10 -08001710
1711 test_->CreateMockRtpSendersReceiversAndChannels(
1712 {}, {},
1713 { std::make_pair(local_video_track.get(), video_sender_info_ssrc1),
1714 std::make_pair(local_video_track.get(), video_sender_info_ssrc2) },
1715 { std::make_pair(remote_video_track_ssrc3.get(),
1716 video_receiver_info_ssrc3),
1717 std::make_pair(remote_video_track_ssrc4.get(),
1718 video_receiver_info_ssrc4) });
hbos09bc1282016-11-08 06:29:22 -08001719
1720 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1721
1722 RTCMediaStreamStats expected_local_stream(
hbos02d2a922016-12-21 01:29:05 -08001723 "RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001724 expected_local_stream.stream_identifier = local_stream->label();
hbos9e302742017-01-20 02:47:10 -08001725 expected_local_stream.track_ids = std::vector<std::string>({
1726 "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1",
1727 "RTCMediaStreamTrack_local_video_LocalVideoTrackID_2" });
hbosdbb64d82016-12-21 01:57:46 -08001728 ASSERT_TRUE(report->Get(expected_local_stream.id()));
hbos09bc1282016-11-08 06:29:22 -08001729 EXPECT_EQ(expected_local_stream,
1730 report->Get(expected_local_stream.id())->cast_to<
1731 RTCMediaStreamStats>());
1732
1733 RTCMediaStreamStats expected_remote_stream(
hbos02d2a922016-12-21 01:29:05 -08001734 "RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001735 expected_remote_stream.stream_identifier = remote_stream->label();
hbos9e302742017-01-20 02:47:10 -08001736 expected_remote_stream.track_ids = std::vector<std::string>({
1737 "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_3",
1738 "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID4_4" });
hbosdbb64d82016-12-21 01:57:46 -08001739 ASSERT_TRUE(report->Get(expected_remote_stream.id()));
hbos09bc1282016-11-08 06:29:22 -08001740 EXPECT_EQ(expected_remote_stream,
1741 report->Get(expected_remote_stream.id())->cast_to<
1742 RTCMediaStreamStats>());
1743
hbos9e302742017-01-20 02:47:10 -08001744 RTCMediaStreamTrackStats expected_local_video_track_ssrc1(
1745 "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1",
1746 report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
1747 expected_local_video_track_ssrc1.track_identifier = local_video_track->id();
1748 expected_local_video_track_ssrc1.remote_source = false;
1749 expected_local_video_track_ssrc1.ended = false;
1750 expected_local_video_track_ssrc1.detached = false;
1751 expected_local_video_track_ssrc1.frame_width = 1234;
1752 expected_local_video_track_ssrc1.frame_height = 4321;
hbosfefe0762017-01-20 06:14:25 -08001753 expected_local_video_track_ssrc1.frames_sent = 11;
hbos9e302742017-01-20 02:47:10 -08001754 ASSERT_TRUE(report->Get(expected_local_video_track_ssrc1.id()));
1755 EXPECT_EQ(expected_local_video_track_ssrc1,
1756 report->Get(expected_local_video_track_ssrc1.id())->cast_to<
hbos09bc1282016-11-08 06:29:22 -08001757 RTCMediaStreamTrackStats>());
1758
hbos9e302742017-01-20 02:47:10 -08001759 RTCMediaStreamTrackStats expected_local_video_track_ssrc2(
1760 "RTCMediaStreamTrack_local_video_LocalVideoTrackID_2",
1761 report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
1762 expected_local_video_track_ssrc2.track_identifier = local_video_track->id();
1763 expected_local_video_track_ssrc2.remote_source = false;
1764 expected_local_video_track_ssrc2.ended = false;
1765 expected_local_video_track_ssrc2.detached = false;
1766 expected_local_video_track_ssrc2.frame_width = 4321;
1767 expected_local_video_track_ssrc2.frame_height = 1234;
hbosfefe0762017-01-20 06:14:25 -08001768 expected_local_video_track_ssrc2.frames_sent = 22;
hbos9e302742017-01-20 02:47:10 -08001769 ASSERT_TRUE(report->Get(expected_local_video_track_ssrc2.id()));
1770 EXPECT_EQ(expected_local_video_track_ssrc2,
1771 report->Get(expected_local_video_track_ssrc2.id())->cast_to<
1772 RTCMediaStreamTrackStats>());
1773
1774 RTCMediaStreamTrackStats expected_remote_video_track_ssrc3(
1775 "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_3",
1776 report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
1777 expected_remote_video_track_ssrc3.track_identifier =
1778 remote_video_track_ssrc3->id();
1779 expected_remote_video_track_ssrc3.remote_source = true;
1780 expected_remote_video_track_ssrc3.ended = true;
1781 expected_remote_video_track_ssrc3.detached = false;
1782 expected_remote_video_track_ssrc3.frame_width = 6789;
1783 expected_remote_video_track_ssrc3.frame_height = 9876;
hbos50cfe1f2017-01-23 07:21:55 -08001784 expected_remote_video_track_ssrc3.frames_received = 1000;
1785 expected_remote_video_track_ssrc3.frames_decoded = 995;
1786 expected_remote_video_track_ssrc3.frames_dropped = 1000 - 990;
hbos9e302742017-01-20 02:47:10 -08001787 ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc3.id()));
1788 EXPECT_EQ(expected_remote_video_track_ssrc3,
1789 report->Get(expected_remote_video_track_ssrc3.id())->cast_to<
1790 RTCMediaStreamTrackStats>());
1791
1792 RTCMediaStreamTrackStats expected_remote_video_track_ssrc4(
1793 "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID4_4",
1794 report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
1795 expected_remote_video_track_ssrc4.track_identifier =
1796 remote_video_track_ssrc4->id();
1797 expected_remote_video_track_ssrc4.remote_source = true;
1798 expected_remote_video_track_ssrc4.ended = false;
1799 expected_remote_video_track_ssrc4.detached = false;
hbos42f6d2f2017-01-20 03:56:50 -08001800 expected_remote_video_track_ssrc4.frames_received = 0;
hbosf64941f2017-01-20 07:39:09 -08001801 expected_remote_video_track_ssrc4.frames_decoded = 0;
hbos50cfe1f2017-01-23 07:21:55 -08001802 expected_remote_video_track_ssrc4.frames_dropped = 0;
hbos9e302742017-01-20 02:47:10 -08001803 // Should be undefined: |expected_remote_video_track_ssrc4.frame_width| and
1804 // |expected_remote_video_track_ssrc4.frame_height|.
1805 ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc4.id()));
1806 EXPECT_EQ(expected_remote_video_track_ssrc4,
1807 report->Get(expected_remote_video_track_ssrc4.id())->cast_to<
hbos09bc1282016-11-08 06:29:22 -08001808 RTCMediaStreamTrackStats>());
1809}
1810
hboseeafe942016-11-01 03:00:17 -07001811TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
1812 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
1813 cricket::VoiceChannel voice_channel(
deadbeefbad5dad2017-01-17 18:32:35 -08001814 test_->worker_thread(), test_->network_thread(),
1815 test_->signaling_thread(), test_->media_engine(), voice_media_channel,
1816 "VoiceContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hboseeafe942016-11-01 03:00:17 -07001817
hbos84abeb12017-01-16 06:16:44 -08001818 test_->SetupRemoteTrackAndReceiver(
1819 cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", 1);
1820
hboseeafe942016-11-01 03:00:17 -07001821 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 02:32:06 -08001822
hboseeafe942016-11-01 03:00:17 -07001823 voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
1824 voice_media_info.receivers[0].local_stats.push_back(
1825 cricket::SsrcReceiverInfo());
1826 voice_media_info.receivers[0].local_stats[0].ssrc = 1;
hbos02cd4d62016-12-09 04:19:44 -08001827 voice_media_info.receivers[0].packets_lost = 42;
hboseeafe942016-11-01 03:00:17 -07001828 voice_media_info.receivers[0].packets_rcvd = 2;
1829 voice_media_info.receivers[0].bytes_rcvd = 3;
hbos0adb8282016-11-23 02:32:06 -08001830 voice_media_info.receivers[0].codec_payload_type = rtc::Optional<int>(42);
hboseeafe942016-11-01 03:00:17 -07001831 voice_media_info.receivers[0].jitter_ms = 4500;
1832 voice_media_info.receivers[0].fraction_lost = 5.5f;
hbos0adb8282016-11-23 02:32:06 -08001833
1834 RtpCodecParameters codec_parameters;
1835 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001836 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1837 codec_parameters.name = "dummy";
1838 codec_parameters.clock_rate = rtc::Optional<int>(0);
hbos0adb8282016-11-23 02:32:06 -08001839 voice_media_info.receive_codecs.insert(
1840 std::make_pair(codec_parameters.payload_type, codec_parameters));
1841
hboseeafe942016-11-01 03:00:17 -07001842 EXPECT_CALL(*voice_media_channel, GetStats(_))
1843 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
1844
1845 SessionStats session_stats;
1846 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
1847 session_stats.transport_stats["TransportName"].transport_name =
1848 "TransportName";
1849
1850 // Make sure the associated |RTCTransportStats| is created.
1851 cricket::TransportChannelStats channel_stats;
1852 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1853 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1854 channel_stats);
1855
hbosdf6075a2016-12-19 04:58:02 -08001856 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1857 [&session_stats](const ChannelNamePairs&) {
1858 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1859 }));
hboseeafe942016-11-01 03:00:17 -07001860 EXPECT_CALL(test_->session(), voice_channel())
1861 .WillRepeatedly(Return(&voice_channel));
1862
1863 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1864
1865 RTCInboundRTPStreamStats expected_audio(
1866 "RTCInboundRTPAudioStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001867 expected_audio.ssrc = 1;
hboseeafe942016-11-01 03:00:17 -07001868 expected_audio.is_remote = false;
1869 expected_audio.media_type = "audio";
hbosb0ae9202017-01-27 06:35:16 -08001870 expected_audio.track_id =
hbos9e302742017-01-20 02:47:10 -08001871 "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_1";
hboseeafe942016-11-01 03:00:17 -07001872 expected_audio.transport_id = "RTCTransport_TransportName_" +
1873 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001874 expected_audio.codec_id = "RTCCodec_InboundAudio_42";
hboseeafe942016-11-01 03:00:17 -07001875 expected_audio.packets_received = 2;
1876 expected_audio.bytes_received = 3;
hbos02cd4d62016-12-09 04:19:44 -08001877 expected_audio.packets_lost = 42;
hboseeafe942016-11-01 03:00:17 -07001878 expected_audio.jitter = 4.5;
1879 expected_audio.fraction_lost = 5.5;
1880
nissec8ee8822017-01-18 07:20:55 -08001881 ASSERT_TRUE(report->Get(expected_audio.id()));
hbosa51d4f32017-02-16 05:34:48 -08001882 EXPECT_EQ(
1883 report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
1884 expected_audio);
hbosb0ae9202017-01-27 06:35:16 -08001885 EXPECT_TRUE(report->Get(*expected_audio.track_id));
hbos84abeb12017-01-16 06:16:44 -08001886 EXPECT_TRUE(report->Get(*expected_audio.transport_id));
1887 EXPECT_TRUE(report->Get(*expected_audio.codec_id));
hboseeafe942016-11-01 03:00:17 -07001888}
1889
1890TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
1891 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
1892 cricket::VideoChannel video_channel(
deadbeefbad5dad2017-01-17 18:32:35 -08001893 test_->worker_thread(), test_->network_thread(),
1894 test_->signaling_thread(), video_media_channel, "VideoContentName",
1895 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hboseeafe942016-11-01 03:00:17 -07001896
hbos84abeb12017-01-16 06:16:44 -08001897 test_->SetupRemoteTrackAndReceiver(
1898 cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", 1);
1899
hboseeafe942016-11-01 03:00:17 -07001900 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 02:32:06 -08001901
hboseeafe942016-11-01 03:00:17 -07001902 video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
1903 video_media_info.receivers[0].local_stats.push_back(
1904 cricket::SsrcReceiverInfo());
1905 video_media_info.receivers[0].local_stats[0].ssrc = 1;
1906 video_media_info.receivers[0].packets_rcvd = 2;
hbos02cd4d62016-12-09 04:19:44 -08001907 video_media_info.receivers[0].packets_lost = 42;
hboseeafe942016-11-01 03:00:17 -07001908 video_media_info.receivers[0].bytes_rcvd = 3;
1909 video_media_info.receivers[0].fraction_lost = 4.5f;
hbos0adb8282016-11-23 02:32:06 -08001910 video_media_info.receivers[0].codec_payload_type = rtc::Optional<int>(42);
hbos820f5782016-11-22 03:16:50 -08001911 video_media_info.receivers[0].firs_sent = 5;
1912 video_media_info.receivers[0].plis_sent = 6;
1913 video_media_info.receivers[0].nacks_sent = 7;
hbos6769c492017-01-02 08:35:13 -08001914 video_media_info.receivers[0].frames_decoded = 8;
hbosa51d4f32017-02-16 05:34:48 -08001915 video_media_info.receivers[0].qp_sum = rtc::Optional<uint64_t>();
hbos0adb8282016-11-23 02:32:06 -08001916
1917 RtpCodecParameters codec_parameters;
1918 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001919 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1920 codec_parameters.name = "dummy";
1921 codec_parameters.clock_rate = rtc::Optional<int>(0);
hbos0adb8282016-11-23 02:32:06 -08001922 video_media_info.receive_codecs.insert(
1923 std::make_pair(codec_parameters.payload_type, codec_parameters));
1924
hboseeafe942016-11-01 03:00:17 -07001925 EXPECT_CALL(*video_media_channel, GetStats(_))
1926 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1927
1928 SessionStats session_stats;
1929 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
1930 session_stats.transport_stats["TransportName"].transport_name =
1931 "TransportName";
1932
1933 // Make sure the associated |RTCTransportStats| is created.
1934 cricket::TransportChannelStats channel_stats;
1935 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1936 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1937 channel_stats);
1938
hbosdf6075a2016-12-19 04:58:02 -08001939 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1940 [&session_stats](const ChannelNamePairs&) {
1941 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1942 }));
hboseeafe942016-11-01 03:00:17 -07001943 EXPECT_CALL(test_->session(), video_channel())
1944 .WillRepeatedly(Return(&video_channel));
1945
1946 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1947
hbos820f5782016-11-22 03:16:50 -08001948 RTCInboundRTPStreamStats expected_video(
hboseeafe942016-11-01 03:00:17 -07001949 "RTCInboundRTPVideoStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001950 expected_video.ssrc = 1;
hbos820f5782016-11-22 03:16:50 -08001951 expected_video.is_remote = false;
1952 expected_video.media_type = "video";
hbosb0ae9202017-01-27 06:35:16 -08001953 expected_video.track_id =
hbos9e302742017-01-20 02:47:10 -08001954 "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID_1";
hbos820f5782016-11-22 03:16:50 -08001955 expected_video.transport_id = "RTCTransport_TransportName_" +
hboseeafe942016-11-01 03:00:17 -07001956 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001957 expected_video.codec_id = "RTCCodec_InboundVideo_42";
hbos820f5782016-11-22 03:16:50 -08001958 expected_video.fir_count = 5;
1959 expected_video.pli_count = 6;
1960 expected_video.nack_count = 7;
1961 expected_video.packets_received = 2;
1962 expected_video.bytes_received = 3;
hbos02cd4d62016-12-09 04:19:44 -08001963 expected_video.packets_lost = 42;
hbos820f5782016-11-22 03:16:50 -08001964 expected_video.fraction_lost = 4.5;
hbos6769c492017-01-02 08:35:13 -08001965 expected_video.frames_decoded = 8;
hbosa51d4f32017-02-16 05:34:48 -08001966 // |expected_video.qp_sum| should be undefined.
hboseeafe942016-11-01 03:00:17 -07001967
nissec8ee8822017-01-18 07:20:55 -08001968 ASSERT_TRUE(report->Get(expected_video.id()));
hbosa51d4f32017-02-16 05:34:48 -08001969 EXPECT_EQ(
1970 report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
1971 expected_video);
hboseeafe942016-11-01 03:00:17 -07001972
hbosa51d4f32017-02-16 05:34:48 -08001973 // Set previously undefined values and "GetStats" again.
1974 video_media_info.receivers[0].qp_sum = rtc::Optional<uint64_t>(9);
1975 expected_video.qp_sum = 9;
1976
1977 EXPECT_CALL(*video_media_channel, GetStats(_))
1978 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1979 collector_->ClearCachedStatsReport();
1980 report = GetStatsReport();
1981
1982 ASSERT_TRUE(report->Get(expected_video.id()));
1983 EXPECT_EQ(
1984 report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
1985 expected_video);
hbosb0ae9202017-01-27 06:35:16 -08001986 EXPECT_TRUE(report->Get(*expected_video.track_id));
hbos84abeb12017-01-16 06:16:44 -08001987 EXPECT_TRUE(report->Get(*expected_video.transport_id));
hbosa51d4f32017-02-16 05:34:48 -08001988 EXPECT_TRUE(report->Get(*expected_video.codec_id));
hboseeafe942016-11-01 03:00:17 -07001989}
1990
hbos6ded1902016-11-01 01:50:46 -07001991TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
1992 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
1993 cricket::VoiceChannel voice_channel(
deadbeefbad5dad2017-01-17 18:32:35 -08001994 test_->worker_thread(), test_->network_thread(),
1995 test_->signaling_thread(), test_->media_engine(), voice_media_channel,
1996 "VoiceContentName", kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hbos6ded1902016-11-01 01:50:46 -07001997
hbos84abeb12017-01-16 06:16:44 -08001998 test_->SetupLocalTrackAndSender(
1999 cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID", 1);
2000
hbos6ded1902016-11-01 01:50:46 -07002001 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 02:32:06 -08002002
hbos6ded1902016-11-01 01:50:46 -07002003 voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
2004 voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
2005 voice_media_info.senders[0].local_stats[0].ssrc = 1;
2006 voice_media_info.senders[0].packets_sent = 2;
2007 voice_media_info.senders[0].bytes_sent = 3;
hbos0adb8282016-11-23 02:32:06 -08002008 voice_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
2009
2010 RtpCodecParameters codec_parameters;
2011 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08002012 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
2013 codec_parameters.name = "dummy";
2014 codec_parameters.clock_rate = rtc::Optional<int>(0);
hbos0adb8282016-11-23 02:32:06 -08002015 voice_media_info.send_codecs.insert(
2016 std::make_pair(codec_parameters.payload_type, codec_parameters));
2017
hbos6ded1902016-11-01 01:50:46 -07002018 EXPECT_CALL(*voice_media_channel, GetStats(_))
2019 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
2020
2021 SessionStats session_stats;
2022 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
2023 session_stats.transport_stats["TransportName"].transport_name =
2024 "TransportName";
2025
2026 // Make sure the associated |RTCTransportStats| is created.
2027 cricket::TransportChannelStats channel_stats;
2028 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbos6ded1902016-11-01 01:50:46 -07002029 session_stats.transport_stats["TransportName"].channel_stats.push_back(
2030 channel_stats);
2031
hbosdf6075a2016-12-19 04:58:02 -08002032 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
2033 [&session_stats](const ChannelNamePairs&) {
2034 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
2035 }));
hbos6ded1902016-11-01 01:50:46 -07002036 EXPECT_CALL(test_->session(), voice_channel())
2037 .WillRepeatedly(Return(&voice_channel));
2038
2039 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
2040
2041 RTCOutboundRTPStreamStats expected_audio(
2042 "RTCOutboundRTPAudioStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08002043 expected_audio.ssrc = 1;
hbos6ded1902016-11-01 01:50:46 -07002044 expected_audio.is_remote = false;
2045 expected_audio.media_type = "audio";
hbosb0ae9202017-01-27 06:35:16 -08002046 expected_audio.track_id =
hbos9e302742017-01-20 02:47:10 -08002047 "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1";
hbos6ded1902016-11-01 01:50:46 -07002048 expected_audio.transport_id = "RTCTransport_TransportName_" +
2049 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08002050 expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
hbos6ded1902016-11-01 01:50:46 -07002051 expected_audio.packets_sent = 2;
2052 expected_audio.bytes_sent = 3;
hboscd195be2017-02-07 08:31:27 -08002053
hboscd195be2017-02-07 08:31:27 -08002054 ASSERT_TRUE(report->Get(expected_audio.id()));
hbosa51d4f32017-02-16 05:34:48 -08002055 EXPECT_EQ(
2056 report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
2057 expected_audio);
skvladed02c6d2017-02-07 10:45:31 -08002058
hbosa51d4f32017-02-16 05:34:48 -08002059 ASSERT_TRUE(report->Get(expected_audio.id()));
2060 EXPECT_EQ(
2061 report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
2062 expected_audio);
hbosb0ae9202017-01-27 06:35:16 -08002063 EXPECT_TRUE(report->Get(*expected_audio.track_id));
hbos84abeb12017-01-16 06:16:44 -08002064 EXPECT_TRUE(report->Get(*expected_audio.transport_id));
2065 EXPECT_TRUE(report->Get(*expected_audio.codec_id));
hbos6ded1902016-11-01 01:50:46 -07002066}
2067
2068TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
2069 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
2070 cricket::VideoChannel video_channel(
deadbeefbad5dad2017-01-17 18:32:35 -08002071 test_->worker_thread(), test_->network_thread(),
2072 test_->signaling_thread(), video_media_channel, "VideoContentName",
2073 kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
hbos6ded1902016-11-01 01:50:46 -07002074
hbos84abeb12017-01-16 06:16:44 -08002075 test_->SetupLocalTrackAndSender(
2076 cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID", 1);
2077
hbos6ded1902016-11-01 01:50:46 -07002078 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 02:32:06 -08002079
hbos6ded1902016-11-01 01:50:46 -07002080 video_media_info.senders.push_back(cricket::VideoSenderInfo());
2081 video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
2082 video_media_info.senders[0].local_stats[0].ssrc = 1;
2083 video_media_info.senders[0].firs_rcvd = 2;
2084 video_media_info.senders[0].plis_rcvd = 3;
2085 video_media_info.senders[0].nacks_rcvd = 4;
2086 video_media_info.senders[0].packets_sent = 5;
2087 video_media_info.senders[0].bytes_sent = 6;
hbos0adb8282016-11-23 02:32:06 -08002088 video_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
hbos6769c492017-01-02 08:35:13 -08002089 video_media_info.senders[0].frames_encoded = 8;
hbosa51d4f32017-02-16 05:34:48 -08002090 video_media_info.senders[0].qp_sum = rtc::Optional<uint64_t>();
hbos0adb8282016-11-23 02:32:06 -08002091
2092 RtpCodecParameters codec_parameters;
2093 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08002094 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
2095 codec_parameters.name = "dummy";
2096 codec_parameters.clock_rate = rtc::Optional<int>(0);
hbos0adb8282016-11-23 02:32:06 -08002097 video_media_info.send_codecs.insert(
2098 std::make_pair(codec_parameters.payload_type, codec_parameters));
2099
hbos6ded1902016-11-01 01:50:46 -07002100 EXPECT_CALL(*video_media_channel, GetStats(_))
2101 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
2102
2103 SessionStats session_stats;
2104 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
2105 session_stats.transport_stats["TransportName"].transport_name =
2106 "TransportName";
2107
2108 // Make sure the associated |RTCTransportStats| is created.
2109 cricket::TransportChannelStats channel_stats;
2110 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbos6ded1902016-11-01 01:50:46 -07002111 session_stats.transport_stats["TransportName"].channel_stats.push_back(
2112 channel_stats);
2113
hbosdf6075a2016-12-19 04:58:02 -08002114 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
2115 [&session_stats](const ChannelNamePairs&) {
2116 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
2117 }));
hbos6ded1902016-11-01 01:50:46 -07002118 EXPECT_CALL(test_->session(), video_channel())
2119 .WillRepeatedly(Return(&video_channel));
2120
2121 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
2122
2123 RTCOutboundRTPStreamStats expected_video(
2124 "RTCOutboundRTPVideoStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08002125 expected_video.ssrc = 1;
hbos6ded1902016-11-01 01:50:46 -07002126 expected_video.is_remote = false;
2127 expected_video.media_type = "video";
hbosb0ae9202017-01-27 06:35:16 -08002128 expected_video.track_id =
hbos9e302742017-01-20 02:47:10 -08002129 "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1";
hbos6ded1902016-11-01 01:50:46 -07002130 expected_video.transport_id = "RTCTransport_TransportName_" +
2131 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08002132 expected_video.codec_id = "RTCCodec_OutboundVideo_42";
hbos6ded1902016-11-01 01:50:46 -07002133 expected_video.fir_count = 2;
2134 expected_video.pli_count = 3;
2135 expected_video.nack_count = 4;
2136 expected_video.packets_sent = 5;
2137 expected_video.bytes_sent = 6;
skvladed02c6d2017-02-07 10:45:31 -08002138 expected_video.frames_encoded = 8;
hbosa7a9be12017-03-01 01:02:45 -08002139 // |expected_video.qp_sum| should be undefined.
hboscd195be2017-02-07 08:31:27 -08002140
2141 ASSERT_TRUE(report->Get(expected_video.id()));
hbosa51d4f32017-02-16 05:34:48 -08002142 EXPECT_EQ(
2143 report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
2144 expected_video);
skvladed02c6d2017-02-07 10:45:31 -08002145
hbosa51d4f32017-02-16 05:34:48 -08002146 // Set previously undefined values and "GetStats" again.
hbosa51d4f32017-02-16 05:34:48 -08002147 video_media_info.senders[0].qp_sum = rtc::Optional<uint64_t>(9);
hbosa51d4f32017-02-16 05:34:48 -08002148 expected_video.qp_sum = 9;
2149
2150 EXPECT_CALL(*video_media_channel, GetStats(_))
2151 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
2152 collector_->ClearCachedStatsReport();
2153 report = GetStatsReport();
2154
2155 ASSERT_TRUE(report->Get(expected_video.id()));
2156 EXPECT_EQ(
2157 report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
2158 expected_video);
hbosb0ae9202017-01-27 06:35:16 -08002159 EXPECT_TRUE(report->Get(*expected_video.track_id));
hbos84abeb12017-01-16 06:16:44 -08002160 EXPECT_TRUE(report->Get(*expected_video.transport_id));
2161 EXPECT_TRUE(report->Get(*expected_video.codec_id));
hbos6ded1902016-11-01 01:50:46 -07002162}
2163
hbos2fa7c672016-10-24 04:00:05 -07002164TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
2165 std::unique_ptr<cricket::Candidate> rtp_local_candidate = CreateFakeCandidate(
2166 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
2167 std::unique_ptr<cricket::Candidate> rtp_remote_candidate =
2168 CreateFakeCandidate("42.42.42.42", 42, "protocol",
2169 cricket::LOCAL_PORT_TYPE, 42);
2170 std::unique_ptr<cricket::Candidate> rtcp_local_candidate =
2171 CreateFakeCandidate("42.42.42.42", 42, "protocol",
2172 cricket::LOCAL_PORT_TYPE, 42);
2173 std::unique_ptr<cricket::Candidate> rtcp_remote_candidate =
2174 CreateFakeCandidate("42.42.42.42", 42, "protocol",
2175 cricket::LOCAL_PORT_TYPE, 42);
2176
2177 SessionStats session_stats;
2178 session_stats.transport_stats["transport"].transport_name = "transport";
2179
2180 cricket::ConnectionInfo rtp_connection_info;
2181 rtp_connection_info.best_connection = false;
2182 rtp_connection_info.local_candidate = *rtp_local_candidate.get();
2183 rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
2184 rtp_connection_info.sent_total_bytes = 42;
2185 rtp_connection_info.recv_total_bytes = 1337;
2186 cricket::TransportChannelStats rtp_transport_channel_stats;
2187 rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
2188 rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info);
hbos7064d592017-01-16 07:38:02 -08002189 rtp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_NEW;
hbos2fa7c672016-10-24 04:00:05 -07002190 session_stats.transport_stats["transport"].channel_stats.push_back(
2191 rtp_transport_channel_stats);
2192
2193
2194 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 04:58:02 -08002195 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
2196 [&session_stats](const ChannelNamePairs&) {
2197 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbos2fa7c672016-10-24 04:00:05 -07002198 }));
2199
2200 // Get stats without RTCP, an active connection or certificates.
2201 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08002202
2203 RTCTransportStats expected_rtp_transport(
2204 "RTCTransport_transport_" +
2205 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP),
2206 report->timestamp_us());
2207 expected_rtp_transport.bytes_sent = 42;
2208 expected_rtp_transport.bytes_received = 1337;
hbos7064d592017-01-16 07:38:02 -08002209 expected_rtp_transport.dtls_state = RTCDtlsTransportState::kNew;
hbos0583b282016-11-30 01:50:14 -08002210
hbosdbb64d82016-12-21 01:57:46 -08002211 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002212 EXPECT_EQ(
2213 expected_rtp_transport,
2214 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07002215
2216 cricket::ConnectionInfo rtcp_connection_info;
2217 rtcp_connection_info.best_connection = false;
2218 rtcp_connection_info.local_candidate = *rtcp_local_candidate.get();
2219 rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get();
2220 rtcp_connection_info.sent_total_bytes = 1337;
2221 rtcp_connection_info.recv_total_bytes = 42;
2222 cricket::TransportChannelStats rtcp_transport_channel_stats;
2223 rtcp_transport_channel_stats.component =
2224 cricket::ICE_CANDIDATE_COMPONENT_RTCP;
2225 rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info);
hbos7064d592017-01-16 07:38:02 -08002226 rtcp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_CONNECTING;
hbos2fa7c672016-10-24 04:00:05 -07002227 session_stats.transport_stats["transport"].channel_stats.push_back(
2228 rtcp_transport_channel_stats);
2229
2230 collector_->ClearCachedStatsReport();
2231 // Get stats with RTCP and without an active connection or certificates.
2232 report = GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08002233
2234 RTCTransportStats expected_rtcp_transport(
2235 "RTCTransport_transport_" +
2236 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTCP),
2237 report->timestamp_us());
2238 expected_rtcp_transport.bytes_sent = 1337;
2239 expected_rtcp_transport.bytes_received = 42;
hbos7064d592017-01-16 07:38:02 -08002240 expected_rtcp_transport.dtls_state = RTCDtlsTransportState::kConnecting;
hbos0583b282016-11-30 01:50:14 -08002241
2242 expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
2243
hbosdbb64d82016-12-21 01:57:46 -08002244 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002245 EXPECT_EQ(
2246 expected_rtp_transport,
2247 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08002248 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002249 EXPECT_EQ(
2250 expected_rtcp_transport,
2251 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07002252
hbos7064d592017-01-16 07:38:02 -08002253 // Get stats with an active connection (selected candidate pair).
hbos0583b282016-11-30 01:50:14 -08002254 session_stats.transport_stats["transport"]
2255 .channel_stats[1]
2256 .connection_infos[0]
2257 .best_connection = true;
hbos2fa7c672016-10-24 04:00:05 -07002258
2259 collector_->ClearCachedStatsReport();
2260 report = GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08002261
hbos0583b282016-11-30 01:50:14 -08002262 expected_rtcp_transport.selected_candidate_pair_id =
2263 "RTCIceCandidatePair_" + rtcp_local_candidate->id() + "_" +
2264 rtcp_remote_candidate->id();
2265
hbosdbb64d82016-12-21 01:57:46 -08002266 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002267 EXPECT_EQ(
2268 expected_rtp_transport,
2269 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08002270 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002271 EXPECT_EQ(
2272 expected_rtcp_transport,
2273 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07002274
2275 // Get stats with certificates.
2276 std::unique_ptr<CertificateInfo> local_certinfo =
2277 CreateFakeCertificateAndInfoFromDers(
2278 std::vector<std::string>({ "(local) local", "(local) chain" }));
2279 std::unique_ptr<CertificateInfo> remote_certinfo =
2280 CreateFakeCertificateAndInfoFromDers(
2281 std::vector<std::string>({ "(remote) local", "(remote) chain" }));
2282 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
eladalon1cc5fc32017-08-23 04:15:18 -07002283 Invoke([&local_certinfo](const std::string& transport_name,
hbos2fa7c672016-10-24 04:00:05 -07002284 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
2285 if (transport_name == "transport") {
2286 *certificate = local_certinfo->certificate;
2287 return true;
2288 }
2289 return false;
2290 }));
2291 EXPECT_CALL(test_->session(),
2292 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
eladalon1cc5fc32017-08-23 04:15:18 -07002293 [&remote_certinfo](const std::string& transport_name) {
hbos2fa7c672016-10-24 04:00:05 -07002294 if (transport_name == "transport")
2295 return remote_certinfo->certificate->ssl_certificate().GetReference();
2296 return static_cast<rtc::SSLCertificate*>(nullptr);
2297 }));
2298
2299 collector_->ClearCachedStatsReport();
2300 report = GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08002301
2302 expected_rtp_transport.local_certificate_id =
2303 "RTCCertificate_" + local_certinfo->fingerprints[0];
2304 expected_rtp_transport.remote_certificate_id =
2305 "RTCCertificate_" + remote_certinfo->fingerprints[0];
2306
2307 expected_rtcp_transport.local_certificate_id =
2308 *expected_rtp_transport.local_certificate_id;
2309 expected_rtcp_transport.remote_certificate_id =
2310 *expected_rtp_transport.remote_certificate_id;
2311
hbosdbb64d82016-12-21 01:57:46 -08002312 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002313 EXPECT_EQ(
2314 expected_rtp_transport,
2315 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08002316 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08002317 EXPECT_EQ(
2318 expected_rtcp_transport,
2319 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07002320}
2321
hbosc82f2e12016-09-05 01:36:50 -07002322class RTCStatsCollectorTestWithFakeCollector : public testing::Test {
2323 public:
2324 RTCStatsCollectorTestWithFakeCollector()
2325 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()),
2326 collector_(FakeRTCStatsCollector::Create(
2327 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) {
2328 }
2329
2330 protected:
2331 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_;
2332 rtc::scoped_refptr<FakeRTCStatsCollector> collector_;
2333};
2334
2335TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) {
2336 collector_->VerifyThreadUsageAndResultsMerging();
2337}
2338
2339} // namespace
2340
hbosd565b732016-08-30 14:04:35 -07002341} // namespace webrtc