blob: 772c76945908a2a881a4e6949c35db1ac42b6abd [file] [log] [blame]
hbosd565b732016-08-30 21:04:351/*
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
hbos74e1a4f2016-09-16 06:33:0111#include "webrtc/api/rtcstatscollector.h"
hbosd565b732016-08-30 21:04:3512
13#include <memory>
hbosda389e32016-10-25 17:55:0814#include <ostream>
hbosd565b732016-08-30 21:04:3515#include <string>
16#include <vector>
17
hbos0adb8282016-11-23 10:32:0618#include "webrtc/api/jsepsessiondescription.h"
hbos09bc1282016-11-08 14:29:2219#include "webrtc/api/mediastream.h"
20#include "webrtc/api/mediastreamtrack.h"
hbos0adb8282016-11-23 10:32:0621#include "webrtc/api/rtpparameters.h"
hbos74e1a4f2016-09-16 06:33:0122#include "webrtc/api/stats/rtcstats_objects.h"
23#include "webrtc/api/stats/rtcstatsreport.h"
hbosd565b732016-08-30 21:04:3524#include "webrtc/api/test/mock_datachannel.h"
25#include "webrtc/api/test/mock_peerconnection.h"
26#include "webrtc/api/test/mock_webrtcsession.h"
hbosdb346a72016-11-29 09:57:0127#include "webrtc/api/test/rtcstatsobtainer.h"
hbosd565b732016-08-30 21:04:3528#include "webrtc/base/checks.h"
hbos0e6758d2016-08-31 14:57:3629#include "webrtc/base/fakeclock.h"
hbos6ab97ce02016-10-03 21:16:5630#include "webrtc/base/fakesslidentity.h"
hbosd565b732016-08-30 21:04:3531#include "webrtc/base/gunit.h"
32#include "webrtc/base/logging.h"
hbosab9f6e42016-10-07 09:18:4733#include "webrtc/base/socketaddress.h"
hbosc82f2e12016-09-05 08:36:5034#include "webrtc/base/thread_checker.h"
hbos0e6758d2016-08-31 14:57:3635#include "webrtc/base/timedelta.h"
36#include "webrtc/base/timeutils.h"
skvlad11a9cbf2016-10-07 18:53:0537#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
hbosd565b732016-08-30 21:04:3538#include "webrtc/media/base/fakemediaengine.h"
hbos6ded1902016-11-01 08:50:4639#include "webrtc/media/base/test/mock_mediachannel.h"
hbos2fa7c672016-10-24 11:00:0540#include "webrtc/p2p/base/p2pconstants.h"
hbosab9f6e42016-10-07 09:18:4741#include "webrtc/p2p/base/port.h"
hbosd565b732016-08-30 21:04:3542
hbos6ab97ce02016-10-03 21:16:5643using testing::_;
44using testing::Invoke;
hbosd565b732016-08-30 21:04:3545using testing::Return;
hbos6ded1902016-11-01 08:50:4646using testing::ReturnNull;
hbosd565b732016-08-30 21:04:3547using testing::ReturnRef;
hbos6ded1902016-11-01 08:50:4648using testing::SetArgPointee;
hbosd565b732016-08-30 21:04:3549
50namespace webrtc {
51
hbosda389e32016-10-25 17:55:0852// These are used by gtest code, such as if |EXPECT_EQ| fails.
53void PrintTo(const RTCCertificateStats& stats, ::std::ostream* os) {
54 *os << stats.ToString();
55}
56
hbos0adb8282016-11-23 10:32:0657void PrintTo(const RTCCodecStats& stats, ::std::ostream* os) {
58 *os << stats.ToString();
59}
60
hbosda389e32016-10-25 17:55:0861void PrintTo(const RTCDataChannelStats& stats, ::std::ostream* os) {
62 *os << stats.ToString();
63}
64
65void PrintTo(const RTCIceCandidatePairStats& stats, ::std::ostream* os) {
66 *os << stats.ToString();
67}
68
69void PrintTo(const RTCLocalIceCandidateStats& stats, ::std::ostream* os) {
70 *os << stats.ToString();
71}
72
73void PrintTo(const RTCRemoteIceCandidateStats& stats, ::std::ostream* os) {
74 *os << stats.ToString();
75}
76
77void PrintTo(const RTCPeerConnectionStats& stats, ::std::ostream* os) {
78 *os << stats.ToString();
79}
80
hbos09bc1282016-11-08 14:29:2281void PrintTo(const RTCMediaStreamStats& stats, ::std::ostream* os) {
82 *os << stats.ToString();
83}
84
85void PrintTo(const RTCMediaStreamTrackStats& stats, ::std::ostream* os) {
86 *os << stats.ToString();
87}
88
hboseeafe942016-11-01 10:00:1789void PrintTo(const RTCInboundRTPStreamStats& stats, ::std::ostream* os) {
90 *os << stats.ToString();
91}
92
hbos6ded1902016-11-01 08:50:4693void PrintTo(const RTCOutboundRTPStreamStats& stats, ::std::ostream* os) {
94 *os << stats.ToString();
95}
96
hbosda389e32016-10-25 17:55:0897void PrintTo(const RTCTransportStats& stats, ::std::ostream* os) {
98 *os << stats.ToString();
99}
100
hbosc82f2e12016-09-05 08:36:50101namespace {
102
103const int64_t kGetStatsReportTimeoutMs = 1000;
deadbeef7af91dd2016-12-13 19:29:11104const bool kDefaultRtcpEnabled = false;
105const bool kDefaultSrtpRequired = true;
hbosc82f2e12016-09-05 08:36:50106
hbos6ab97ce02016-10-03 21:16:56107struct CertificateInfo {
108 rtc::scoped_refptr<rtc::RTCCertificate> certificate;
109 std::vector<std::string> ders;
110 std::vector<std::string> pems;
111 std::vector<std::string> fingerprints;
112};
113
114std::unique_ptr<CertificateInfo> CreateFakeCertificateAndInfoFromDers(
115 const std::vector<std::string>& ders) {
116 RTC_CHECK(!ders.empty());
117 std::unique_ptr<CertificateInfo> info(new CertificateInfo());
118 info->ders = ders;
119 for (const std::string& der : ders) {
120 info->pems.push_back(rtc::SSLIdentity::DerToPem(
121 "CERTIFICATE",
122 reinterpret_cast<const unsigned char*>(der.c_str()),
123 der.length()));
124 }
125 info->certificate =
126 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
127 new rtc::FakeSSLIdentity(rtc::FakeSSLCertificate(info->pems))));
128 // Strip header/footer and newline characters of PEM strings.
129 for (size_t i = 0; i < info->pems.size(); ++i) {
130 rtc::replace_substrs("-----BEGIN CERTIFICATE-----", 27,
131 "", 0, &info->pems[i]);
132 rtc::replace_substrs("-----END CERTIFICATE-----", 25,
133 "", 0, &info->pems[i]);
134 rtc::replace_substrs("\n", 1,
135 "", 0, &info->pems[i]);
136 }
137 // Fingerprint of leaf certificate.
138 std::unique_ptr<rtc::SSLFingerprint> fp(
139 rtc::SSLFingerprint::Create("sha-1",
140 &info->certificate->ssl_certificate()));
141 EXPECT_TRUE(fp);
142 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
143 // Fingerprints of the rest of the chain.
144 std::unique_ptr<rtc::SSLCertChain> chain =
145 info->certificate->ssl_certificate().GetChain();
146 if (chain) {
147 for (size_t i = 0; i < chain->GetSize(); i++) {
148 fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain->Get(i)));
149 EXPECT_TRUE(fp);
150 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
151 }
152 }
153 EXPECT_EQ(info->ders.size(), info->fingerprints.size());
154 return info;
155}
156
hbosab9f6e42016-10-07 09:18:47157std::unique_ptr<cricket::Candidate> CreateFakeCandidate(
158 const std::string& hostname,
159 int port,
160 const std::string& protocol,
161 const std::string& candidate_type,
162 uint32_t priority) {
163 std::unique_ptr<cricket::Candidate> candidate(new cricket::Candidate());
164 candidate->set_address(rtc::SocketAddress(hostname, port));
165 candidate->set_protocol(protocol);
166 candidate->set_type(candidate_type);
167 candidate->set_priority(priority);
168 return candidate;
169}
170
hbos09bc1282016-11-08 14:29:22171class FakeAudioProcessorForStats
172 : public rtc::RefCountedObject<AudioProcessorInterface> {
173 public:
174 FakeAudioProcessorForStats(
175 AudioProcessorInterface::AudioProcessorStats stats)
176 : stats_(stats) {
177 }
178
179 void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
180 *stats = stats_;
181 }
182
183 private:
184 AudioProcessorInterface::AudioProcessorStats stats_;
185};
186
187class FakeAudioTrackForStats
188 : public MediaStreamTrack<AudioTrackInterface> {
189 public:
190 static rtc::scoped_refptr<FakeAudioTrackForStats> Create(
191 const std::string& id,
192 MediaStreamTrackInterface::TrackState state,
193 int signal_level,
194 rtc::scoped_refptr<FakeAudioProcessorForStats> processor) {
195 rtc::scoped_refptr<FakeAudioTrackForStats> audio_track_stats(
196 new rtc::RefCountedObject<FakeAudioTrackForStats>(
197 id, signal_level, processor));
198 audio_track_stats->set_state(state);
199 return audio_track_stats;
200 }
201
202 FakeAudioTrackForStats(
203 const std::string& id,
204 int signal_level,
205 rtc::scoped_refptr<FakeAudioProcessorForStats> processor)
206 : MediaStreamTrack<AudioTrackInterface>(id),
207 signal_level_(signal_level),
208 processor_(processor) {
209 }
210
211 std::string kind() const override {
212 return MediaStreamTrackInterface::kAudioKind;
213 }
214 webrtc::AudioSourceInterface* GetSource() const override { return nullptr; }
215 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
216 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
217 bool GetSignalLevel(int* level) override {
218 *level = signal_level_;
219 return true;
220 }
221 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
222 return processor_;
223 }
224
225 private:
226 int signal_level_;
227 rtc::scoped_refptr<FakeAudioProcessorForStats> processor_;
228};
229
230class FakeVideoTrackSourceForStats
231 : public rtc::RefCountedObject<VideoTrackSourceInterface> {
232 public:
233 FakeVideoTrackSourceForStats(VideoTrackSourceInterface::Stats stats)
234 : stats_(stats) {
235 }
236
237 MediaSourceInterface::SourceState state() const override {
238 return MediaSourceInterface::kLive;
239 }
240 bool remote() const override { return false; }
241 void RegisterObserver(ObserverInterface* observer) override {}
242 void UnregisterObserver(ObserverInterface* observer) override {}
nisseacd935b2016-11-11 11:55:13243 void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
hbos09bc1282016-11-08 14:29:22244 const rtc::VideoSinkWants& wants) override {}
nisseacd935b2016-11-11 11:55:13245 void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
hbos09bc1282016-11-08 14:29:22246 }
247 bool is_screencast() const override { return false; }
248 rtc::Optional<bool> needs_denoising() const override {
249 return rtc::Optional<bool>();
250 }
251 bool GetStats(VideoTrackSourceInterface::Stats* stats) override {
252 *stats = stats_;
253 return true;
254 }
255
256 private:
257 VideoTrackSourceInterface::Stats stats_;
258};
259
260class FakeVideoTrackForStats
261 : public MediaStreamTrack<VideoTrackInterface> {
262 public:
263 static rtc::scoped_refptr<FakeVideoTrackForStats> Create(
264 const std::string& id,
265 MediaStreamTrackInterface::TrackState state,
266 rtc::scoped_refptr<VideoTrackSourceInterface> source) {
267 rtc::scoped_refptr<FakeVideoTrackForStats> video_track(
268 new rtc::RefCountedObject<FakeVideoTrackForStats>(id, source));
269 video_track->set_state(state);
270 return video_track;
271 }
272
273 FakeVideoTrackForStats(
274 const std::string& id,
275 rtc::scoped_refptr<VideoTrackSourceInterface> source)
276 : MediaStreamTrack<VideoTrackInterface>(id),
277 source_(source) {
278 }
279
280 std::string kind() const override {
281 return MediaStreamTrackInterface::kVideoKind;
282 }
283 VideoTrackSourceInterface* GetSource() const override {
284 return source_;
285 }
286
287 private:
288 rtc::scoped_refptr<VideoTrackSourceInterface> source_;
289};
290
hbosc82f2e12016-09-05 08:36:50291class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
hbosd565b732016-08-30 21:04:35292 public:
hbosc82f2e12016-09-05 08:36:50293 RTCStatsCollectorTestHelper()
hbosd565b732016-08-30 21:04:35294 : worker_thread_(rtc::Thread::Current()),
295 network_thread_(rtc::Thread::Current()),
hbos6ded1902016-11-01 08:50:46296 media_engine_(new cricket::FakeMediaEngine()),
skvlad11a9cbf2016-10-07 18:53:05297 channel_manager_(
hbos6ded1902016-11-01 08:50:46298 new cricket::ChannelManager(media_engine_,
skvlad11a9cbf2016-10-07 18:53:05299 worker_thread_,
300 network_thread_)),
hbosd565b732016-08-30 21:04:35301 media_controller_(
302 MediaControllerInterface::Create(cricket::MediaConfig(),
303 worker_thread_,
skvlad11a9cbf2016-10-07 18:53:05304 channel_manager_.get(),
305 &event_log_)),
hbosd565b732016-08-30 21:04:35306 session_(media_controller_.get()),
307 pc_() {
hbos6ab97ce02016-10-03 21:16:56308 // Default return values for mocks.
hbos09bc1282016-11-08 14:29:22309 EXPECT_CALL(pc_, local_streams()).WillRepeatedly(Return(nullptr));
310 EXPECT_CALL(pc_, remote_streams()).WillRepeatedly(Return(nullptr));
hbosd565b732016-08-30 21:04:35311 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
312 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly(
313 ReturnRef(data_channels_));
hbos6ded1902016-11-01 08:50:46314 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
315 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
hbosdf6075a2016-12-19 12:58:02316 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(ReturnNull());
hbosab9f6e42016-10-07 09:18:47317 EXPECT_CALL(session_, GetLocalCertificate(_, _)).WillRepeatedly(
318 Return(false));
319 EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
320 .WillRepeatedly(Return(nullptr));
hbosd565b732016-08-30 21:04:35321 }
322
hbosfdafab82016-09-14 13:02:13323 rtc::ScopedFakeClock& fake_clock() { return fake_clock_; }
hbos6ded1902016-11-01 08:50:46324 rtc::Thread* worker_thread() { return worker_thread_; }
325 rtc::Thread* network_thread() { return network_thread_; }
326 cricket::FakeMediaEngine* media_engine() { return media_engine_; }
hbosd565b732016-08-30 21:04:35327 MockWebRtcSession& session() { return session_; }
328 MockPeerConnection& pc() { return pc_; }
329 std::vector<rtc::scoped_refptr<DataChannel>>& data_channels() {
330 return data_channels_;
331 }
332
333 // SetSessionDescriptionObserver overrides.
334 void OnSuccess() override {}
335 void OnFailure(const std::string& error) override {
336 RTC_NOTREACHED() << error;
337 }
338
339 private:
hbosfdafab82016-09-14 13:02:13340 rtc::ScopedFakeClock fake_clock_;
hbos09bc1282016-11-08 14:29:22341 RtcEventLogNullImpl event_log_;
hbosd565b732016-08-30 21:04:35342 rtc::Thread* const worker_thread_;
343 rtc::Thread* const network_thread_;
hbos6ded1902016-11-01 08:50:46344 cricket::FakeMediaEngine* media_engine_;
hbosd565b732016-08-30 21:04:35345 std::unique_ptr<cricket::ChannelManager> channel_manager_;
hbos09bc1282016-11-08 14:29:22346 std::unique_ptr<MediaControllerInterface> media_controller_;
hbosd565b732016-08-30 21:04:35347 MockWebRtcSession session_;
348 MockPeerConnection pc_;
349
350 std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
351};
352
hbosc82f2e12016-09-05 08:36:50353class RTCTestStats : public RTCStats {
hbosd565b732016-08-30 21:04:35354 public:
hbosfc5e0502016-10-06 09:06:10355 WEBRTC_RTCSTATS_DECL();
356
hbosc82f2e12016-09-05 08:36:50357 RTCTestStats(const std::string& id, int64_t timestamp_us)
358 : RTCStats(id, timestamp_us),
359 dummy_stat("dummyStat") {}
360
hbosc82f2e12016-09-05 08:36:50361 RTCStatsMember<int32_t> dummy_stat;
362};
363
hbosfc5e0502016-10-06 09:06:10364WEBRTC_RTCSTATS_IMPL(RTCTestStats, RTCStats, "test-stats",
365 &dummy_stat);
hbosc82f2e12016-09-05 08:36:50366
367// Overrides the stats collection to verify thread usage and that the resulting
368// partial reports are merged.
369class FakeRTCStatsCollector : public RTCStatsCollector,
370 public RTCStatsCollectorCallback {
371 public:
372 static rtc::scoped_refptr<FakeRTCStatsCollector> Create(
373 PeerConnection* pc,
374 int64_t cache_lifetime_us) {
375 return rtc::scoped_refptr<FakeRTCStatsCollector>(
376 new rtc::RefCountedObject<FakeRTCStatsCollector>(
377 pc, cache_lifetime_us));
378 }
379
380 // RTCStatsCollectorCallback implementation.
381 void OnStatsDelivered(
382 const rtc::scoped_refptr<const RTCStatsReport>& report) override {
383 EXPECT_TRUE(signaling_thread_->IsCurrent());
384 rtc::CritScope cs(&lock_);
385 delivered_report_ = report;
386 }
387
388 void VerifyThreadUsageAndResultsMerging() {
389 GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback>(this));
390 EXPECT_TRUE_WAIT(HasVerifiedResults(), kGetStatsReportTimeoutMs);
391 }
392
393 bool HasVerifiedResults() {
394 EXPECT_TRUE(signaling_thread_->IsCurrent());
395 rtc::CritScope cs(&lock_);
396 if (!delivered_report_)
397 return false;
398 EXPECT_EQ(produced_on_signaling_thread_, 1);
399 EXPECT_EQ(produced_on_worker_thread_, 1);
400 EXPECT_EQ(produced_on_network_thread_, 1);
401
402 EXPECT_TRUE(delivered_report_->Get("SignalingThreadStats"));
403 EXPECT_TRUE(delivered_report_->Get("WorkerThreadStats"));
404 EXPECT_TRUE(delivered_report_->Get("NetworkThreadStats"));
405
406 produced_on_signaling_thread_ = 0;
407 produced_on_worker_thread_ = 0;
408 produced_on_network_thread_ = 0;
409 delivered_report_ = nullptr;
410 return true;
hbosd565b732016-08-30 21:04:35411 }
412
413 protected:
hbosc82f2e12016-09-05 08:36:50414 FakeRTCStatsCollector(
415 PeerConnection* pc,
416 int64_t cache_lifetime)
417 : RTCStatsCollector(pc, cache_lifetime),
418 signaling_thread_(pc->session()->signaling_thread()),
419 worker_thread_(pc->session()->worker_thread()),
420 network_thread_(pc->session()->network_thread()) {
421 }
422
423 void ProducePartialResultsOnSignalingThread(int64_t timestamp_us) override {
424 EXPECT_TRUE(signaling_thread_->IsCurrent());
425 {
426 rtc::CritScope cs(&lock_);
427 EXPECT_FALSE(delivered_report_);
428 ++produced_on_signaling_thread_;
429 }
430
431 rtc::scoped_refptr<RTCStatsReport> signaling_report =
hbos6ded1902016-11-01 08:50:46432 RTCStatsReport::Create(0);
hbosc82f2e12016-09-05 08:36:50433 signaling_report->AddStats(std::unique_ptr<const RTCStats>(
434 new RTCTestStats("SignalingThreadStats", timestamp_us)));
435 AddPartialResults(signaling_report);
436 }
437 void ProducePartialResultsOnWorkerThread(int64_t timestamp_us) override {
438 EXPECT_TRUE(worker_thread_->IsCurrent());
439 {
440 rtc::CritScope cs(&lock_);
441 EXPECT_FALSE(delivered_report_);
442 ++produced_on_worker_thread_;
443 }
444
hbos6ded1902016-11-01 08:50:46445 rtc::scoped_refptr<RTCStatsReport> worker_report =
446 RTCStatsReport::Create(0);
hbosc82f2e12016-09-05 08:36:50447 worker_report->AddStats(std::unique_ptr<const RTCStats>(
448 new RTCTestStats("WorkerThreadStats", timestamp_us)));
449 AddPartialResults(worker_report);
450 }
451 void ProducePartialResultsOnNetworkThread(int64_t timestamp_us) override {
452 EXPECT_TRUE(network_thread_->IsCurrent());
453 {
454 rtc::CritScope cs(&lock_);
455 EXPECT_FALSE(delivered_report_);
456 ++produced_on_network_thread_;
457 }
458
459 rtc::scoped_refptr<RTCStatsReport> network_report =
hbos6ded1902016-11-01 08:50:46460 RTCStatsReport::Create(0);
hbosc82f2e12016-09-05 08:36:50461 network_report->AddStats(std::unique_ptr<const RTCStats>(
462 new RTCTestStats("NetworkThreadStats", timestamp_us)));
463 AddPartialResults(network_report);
464 }
465
466 private:
467 rtc::Thread* const signaling_thread_;
468 rtc::Thread* const worker_thread_;
469 rtc::Thread* const network_thread_;
470
471 rtc::CriticalSection lock_;
472 rtc::scoped_refptr<const RTCStatsReport> delivered_report_;
473 int produced_on_signaling_thread_ = 0;
474 int produced_on_worker_thread_ = 0;
475 int produced_on_network_thread_ = 0;
hbosd565b732016-08-30 21:04:35476};
477
hbosc82f2e12016-09-05 08:36:50478class RTCStatsCollectorTest : public testing::Test {
479 public:
480 RTCStatsCollectorTest()
481 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()),
482 collector_(RTCStatsCollector::Create(
483 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) {
484 }
485
486 rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() {
hbosdb346a72016-11-29 09:57:01487 rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
hbosc82f2e12016-09-05 08:36:50488 collector_->GetStatsReport(callback);
489 EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs);
hboscc555c52016-10-18 19:48:31490 int64_t after = rtc::TimeUTCMicros();
491 for (const RTCStats& stats : *callback->report()) {
492 EXPECT_LE(stats.timestamp_us(), after);
493 }
hbosc82f2e12016-09-05 08:36:50494 return callback->report();
495 }
496
hbosc47a0c32016-10-11 21:54:49497 const RTCIceCandidateStats* ExpectReportContainsCandidate(
hbosab9f6e42016-10-07 09:18:47498 const rtc::scoped_refptr<const RTCStatsReport>& report,
499 const cricket::Candidate& candidate,
500 bool is_local) {
hbosc47a0c32016-10-11 21:54:49501 const RTCStats* stats = report->Get("RTCIceCandidate_" + candidate.id());
hbosab9f6e42016-10-07 09:18:47502 EXPECT_TRUE(stats);
503 const RTCIceCandidateStats* candidate_stats;
504 if (is_local)
505 candidate_stats = &stats->cast_to<RTCLocalIceCandidateStats>();
506 else
507 candidate_stats = &stats->cast_to<RTCRemoteIceCandidateStats>();
508 EXPECT_EQ(*candidate_stats->ip, candidate.address().ipaddr().ToString());
509 EXPECT_EQ(*candidate_stats->port,
510 static_cast<int32_t>(candidate.address().port()));
511 EXPECT_EQ(*candidate_stats->protocol, candidate.protocol());
512 EXPECT_EQ(*candidate_stats->candidate_type,
hboscc555c52016-10-18 19:48:31513 CandidateTypeToRTCIceCandidateTypeForTesting(candidate.type()));
hbosab9f6e42016-10-07 09:18:47514 EXPECT_EQ(*candidate_stats->priority,
515 static_cast<int32_t>(candidate.priority()));
516 // TODO(hbos): Define candidate_stats->url. crbug.com/632723
517 EXPECT_FALSE(candidate_stats->url.is_defined());
hbosc47a0c32016-10-11 21:54:49518 return candidate_stats;
519 }
520
hbos6ab97ce02016-10-03 21:16:56521 void ExpectReportContainsCertificateInfo(
522 const rtc::scoped_refptr<const RTCStatsReport>& report,
523 const CertificateInfo& cert_info) {
524 for (size_t i = 0; i < cert_info.fingerprints.size(); ++i) {
525 const RTCStats* stats = report->Get(
526 "RTCCertificate_" + cert_info.fingerprints[i]);
hbos2fa7c672016-10-24 11:00:05527 ASSERT_TRUE(stats);
hbos6ab97ce02016-10-03 21:16:56528 const RTCCertificateStats& cert_stats =
529 stats->cast_to<const RTCCertificateStats>();
530 EXPECT_EQ(*cert_stats.fingerprint, cert_info.fingerprints[i]);
531 EXPECT_EQ(*cert_stats.fingerprint_algorithm, "sha-1");
532 EXPECT_EQ(*cert_stats.base64_certificate, cert_info.pems[i]);
533 if (i + 1 < cert_info.fingerprints.size()) {
534 EXPECT_EQ(*cert_stats.issuer_certificate_id,
535 "RTCCertificate_" + cert_info.fingerprints[i + 1]);
536 } else {
537 EXPECT_FALSE(cert_stats.issuer_certificate_id.is_defined());
538 }
539 }
540 }
541
hbosc82f2e12016-09-05 08:36:50542 protected:
543 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_;
544 rtc::scoped_refptr<RTCStatsCollector> collector_;
545};
546
547TEST_F(RTCStatsCollectorTest, SingleCallback) {
548 rtc::scoped_refptr<const RTCStatsReport> result;
hbosdb346a72016-11-29 09:57:01549 collector_->GetStatsReport(RTCStatsObtainer::Create(&result));
hbosc82f2e12016-09-05 08:36:50550 EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs);
551}
552
553TEST_F(RTCStatsCollectorTest, MultipleCallbacks) {
554 rtc::scoped_refptr<const RTCStatsReport> a;
555 rtc::scoped_refptr<const RTCStatsReport> b;
556 rtc::scoped_refptr<const RTCStatsReport> c;
hbosdb346a72016-11-29 09:57:01557 collector_->GetStatsReport(RTCStatsObtainer::Create(&a));
558 collector_->GetStatsReport(RTCStatsObtainer::Create(&b));
559 collector_->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 08:36:50560 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
561 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
562 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
563 EXPECT_EQ(a.get(), b.get());
564 EXPECT_EQ(b.get(), c.get());
565}
566
567TEST_F(RTCStatsCollectorTest, CachedStatsReports) {
hbosd565b732016-08-30 21:04:35568 // Caching should ensure |a| and |b| are the same report.
hbosc82f2e12016-09-05 08:36:50569 rtc::scoped_refptr<const RTCStatsReport> a = GetStatsReport();
570 rtc::scoped_refptr<const RTCStatsReport> b = GetStatsReport();
hbosd565b732016-08-30 21:04:35571 EXPECT_EQ(a.get(), b.get());
572 // Invalidate cache by clearing it.
hbosc82f2e12016-09-05 08:36:50573 collector_->ClearCachedStatsReport();
574 rtc::scoped_refptr<const RTCStatsReport> c = GetStatsReport();
hbosd565b732016-08-30 21:04:35575 EXPECT_NE(b.get(), c.get());
576 // Invalidate cache by advancing time.
hbosfdafab82016-09-14 13:02:13577 test_->fake_clock().AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
hbosc82f2e12016-09-05 08:36:50578 rtc::scoped_refptr<const RTCStatsReport> d = GetStatsReport();
hbosd565b732016-08-30 21:04:35579 EXPECT_TRUE(d);
580 EXPECT_NE(c.get(), d.get());
581}
582
hbosc82f2e12016-09-05 08:36:50583TEST_F(RTCStatsCollectorTest, MultipleCallbacksWithInvalidatedCacheInBetween) {
hbosc82f2e12016-09-05 08:36:50584 rtc::scoped_refptr<const RTCStatsReport> a;
585 rtc::scoped_refptr<const RTCStatsReport> b;
586 rtc::scoped_refptr<const RTCStatsReport> c;
hbosdb346a72016-11-29 09:57:01587 collector_->GetStatsReport(RTCStatsObtainer::Create(&a));
588 collector_->GetStatsReport(RTCStatsObtainer::Create(&b));
hbosc82f2e12016-09-05 08:36:50589 // Cache is invalidated after 50 ms.
hbosfdafab82016-09-14 13:02:13590 test_->fake_clock().AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
hbosdb346a72016-11-29 09:57:01591 collector_->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 08:36:50592 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
593 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
594 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
595 EXPECT_EQ(a.get(), b.get());
596 // The act of doing |AdvanceTime| processes all messages. If this was not the
597 // case we might not require |c| to be fresher than |b|.
598 EXPECT_NE(c.get(), b.get());
599}
600
hbos6ab97ce02016-10-03 21:16:56601TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) {
602 std::unique_ptr<CertificateInfo> local_certinfo =
603 CreateFakeCertificateAndInfoFromDers(
604 std::vector<std::string>({ "(local) single certificate" }));
605 std::unique_ptr<CertificateInfo> remote_certinfo =
606 CreateFakeCertificateAndInfoFromDers(
607 std::vector<std::string>({ "(remote) single certificate" }));
608
609 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 12:58:02610 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
611 [this](const ChannelNamePairs&) {
612 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce02016-10-03 21:16:56613 stats->transport_stats["transport"].transport_name = "transport";
hbosdf6075a2016-12-19 12:58:02614 return stats;
hbos6ab97ce02016-10-03 21:16:56615 }));
616 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
617 Invoke([this, &local_certinfo](const std::string& transport_name,
618 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
619 if (transport_name == "transport") {
620 *certificate = local_certinfo->certificate;
621 return true;
622 }
623 return false;
624 }));
625 EXPECT_CALL(test_->session(),
626 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
627 [this, &remote_certinfo](const std::string& transport_name) {
628 if (transport_name == "transport")
629 return remote_certinfo->certificate->ssl_certificate().GetReference();
630 return static_cast<rtc::SSLCertificate*>(nullptr);
631 }));
632
633 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
634 ExpectReportContainsCertificateInfo(report, *local_certinfo.get());
635 ExpectReportContainsCertificateInfo(report, *remote_certinfo.get());
636}
637
hbos0adb8282016-11-23 10:32:06638TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
639 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
640 cricket::VoiceChannel voice_channel(
641 test_->worker_thread(), test_->network_thread(), test_->media_engine(),
deadbeef7af91dd2016-12-13 19:29:11642 voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled,
643 kDefaultSrtpRequired);
hbos0adb8282016-11-23 10:32:06644
645 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
646 cricket::VideoChannel video_channel(
647 test_->worker_thread(), test_->network_thread(), video_media_channel,
deadbeef7af91dd2016-12-13 19:29:11648 nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired);
hbos0adb8282016-11-23 10:32:06649
650 // Audio
651 cricket::VoiceMediaInfo voice_media_info;
652
653 RtpCodecParameters inbound_audio_codec;
654 inbound_audio_codec.payload_type = 1;
655 inbound_audio_codec.mime_type = "opus";
656 inbound_audio_codec.clock_rate = 1337;
657 voice_media_info.receive_codecs.insert(
658 std::make_pair(inbound_audio_codec.payload_type, inbound_audio_codec));
659
660 RtpCodecParameters outbound_audio_codec;
661 outbound_audio_codec.payload_type = 2;
662 outbound_audio_codec.mime_type = "isac";
663 outbound_audio_codec.clock_rate = 1338;
664 voice_media_info.send_codecs.insert(
665 std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
666
667 EXPECT_CALL(*voice_media_channel, GetStats(_))
668 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
669
670 // Video
671 cricket::VideoMediaInfo video_media_info;
672
673 RtpCodecParameters inbound_video_codec;
674 inbound_video_codec.payload_type = 3;
675 inbound_video_codec.mime_type = "H264";
676 inbound_video_codec.clock_rate = 1339;
677 video_media_info.receive_codecs.insert(
678 std::make_pair(inbound_video_codec.payload_type, inbound_video_codec));
679
680 RtpCodecParameters outbound_video_codec;
681 outbound_video_codec.payload_type = 4;
682 outbound_video_codec.mime_type = "VP8";
683 outbound_video_codec.clock_rate = 1340;
684 video_media_info.send_codecs.insert(
685 std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
686
687 EXPECT_CALL(*video_media_channel, GetStats(_))
688 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
689
690 SessionStats session_stats;
691 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
692 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
693 session_stats.transport_stats["TransportName"].transport_name =
694 "TransportName";
695
hbosdf6075a2016-12-19 12:58:02696 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
697 [&session_stats](const ChannelNamePairs&) {
698 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
699 }));
hbos0adb8282016-11-23 10:32:06700 EXPECT_CALL(test_->session(), voice_channel())
701 .WillRepeatedly(Return(&voice_channel));
702 EXPECT_CALL(test_->session(), video_channel())
703 .WillRepeatedly(Return(&video_channel));
704
705 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
706
707 RTCCodecStats expected_inbound_audio_codec(
708 "RTCCodec_InboundAudio_1", report->timestamp_us());
709 expected_inbound_audio_codec.payload_type = 1;
710 expected_inbound_audio_codec.codec = "audio/opus";
711 expected_inbound_audio_codec.clock_rate = 1337;
712
713 RTCCodecStats expected_outbound_audio_codec(
714 "RTCCodec_OutboundAudio_2", report->timestamp_us());
715 expected_outbound_audio_codec.payload_type = 2;
716 expected_outbound_audio_codec.codec = "audio/isac";
717 expected_outbound_audio_codec.clock_rate = 1338;
718
719 RTCCodecStats expected_inbound_video_codec(
720 "RTCCodec_InboundVideo_3", report->timestamp_us());
721 expected_inbound_video_codec.payload_type = 3;
722 expected_inbound_video_codec.codec = "video/H264";
723 expected_inbound_video_codec.clock_rate = 1339;
724
725 RTCCodecStats expected_outbound_video_codec(
726 "RTCCodec_OutboundVideo_4", report->timestamp_us());
727 expected_outbound_video_codec.payload_type = 4;
728 expected_outbound_video_codec.codec = "video/VP8";
729 expected_outbound_video_codec.clock_rate = 1340;
730
731 ASSERT(report->Get(expected_inbound_audio_codec.id()));
732 EXPECT_EQ(expected_inbound_audio_codec,
733 report->Get(expected_inbound_audio_codec.id())->cast_to<
734 RTCCodecStats>());
735
736 ASSERT(report->Get(expected_outbound_audio_codec.id()));
737 EXPECT_EQ(expected_outbound_audio_codec,
738 report->Get(expected_outbound_audio_codec.id())->cast_to<
739 RTCCodecStats>());
740
741 ASSERT(report->Get(expected_inbound_video_codec.id()));
742 EXPECT_EQ(expected_inbound_video_codec,
743 report->Get(expected_inbound_video_codec.id())->cast_to<
744 RTCCodecStats>());
745
746 ASSERT(report->Get(expected_outbound_video_codec.id()));
747 EXPECT_EQ(expected_outbound_video_codec,
748 report->Get(expected_outbound_video_codec.id())->cast_to<
749 RTCCodecStats>());
750}
751
hbos6ab97ce02016-10-03 21:16:56752TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
753 std::unique_ptr<CertificateInfo> audio_local_certinfo =
754 CreateFakeCertificateAndInfoFromDers(
755 std::vector<std::string>({ "(local) audio" }));
756 audio_local_certinfo = CreateFakeCertificateAndInfoFromDers(
757 audio_local_certinfo->ders);
758 std::unique_ptr<CertificateInfo> audio_remote_certinfo =
759 CreateFakeCertificateAndInfoFromDers(
760 std::vector<std::string>({ "(remote) audio" }));
761 audio_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
762 audio_remote_certinfo->ders);
763
764 std::unique_ptr<CertificateInfo> video_local_certinfo =
765 CreateFakeCertificateAndInfoFromDers(
766 std::vector<std::string>({ "(local) video" }));
767 video_local_certinfo = CreateFakeCertificateAndInfoFromDers(
768 video_local_certinfo->ders);
769 std::unique_ptr<CertificateInfo> video_remote_certinfo =
770 CreateFakeCertificateAndInfoFromDers(
771 std::vector<std::string>({ "(remote) video" }));
772 video_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
773 video_remote_certinfo->ders);
774
775 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 12:58:02776 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
777 [this](const ChannelNamePairs&) {
778 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce02016-10-03 21:16:56779 stats->transport_stats["audio"].transport_name = "audio";
780 stats->transport_stats["video"].transport_name = "video";
hbosdf6075a2016-12-19 12:58:02781 return stats;
hbos6ab97ce02016-10-03 21:16:56782 }));
783 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
784 Invoke([this, &audio_local_certinfo, &video_local_certinfo](
785 const std::string& transport_name,
786 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
787 if (transport_name == "audio") {
788 *certificate = audio_local_certinfo->certificate;
789 return true;
790 }
791 if (transport_name == "video") {
792 *certificate = video_local_certinfo->certificate;
793 return true;
794 }
795 return false;
796 }));
797 EXPECT_CALL(test_->session(),
798 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
799 [this, &audio_remote_certinfo, &video_remote_certinfo](
800 const std::string& transport_name) {
801 if (transport_name == "audio") {
802 return audio_remote_certinfo->certificate->ssl_certificate()
803 .GetReference();
804 }
805 if (transport_name == "video") {
806 return video_remote_certinfo->certificate->ssl_certificate()
807 .GetReference();
808 }
809 return static_cast<rtc::SSLCertificate*>(nullptr);
810 }));
811
812 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
813 ExpectReportContainsCertificateInfo(report, *audio_local_certinfo.get());
814 ExpectReportContainsCertificateInfo(report, *audio_remote_certinfo.get());
815 ExpectReportContainsCertificateInfo(report, *video_local_certinfo.get());
816 ExpectReportContainsCertificateInfo(report, *video_remote_certinfo.get());
817}
818
819TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
820 std::vector<std::string> local_ders;
821 local_ders.push_back("(local) this");
822 local_ders.push_back("(local) is");
823 local_ders.push_back("(local) a");
824 local_ders.push_back("(local) chain");
825 std::unique_ptr<CertificateInfo> local_certinfo =
826 CreateFakeCertificateAndInfoFromDers(local_ders);
827 std::vector<std::string> remote_ders;
828 remote_ders.push_back("(remote) this");
829 remote_ders.push_back("(remote) is");
830 remote_ders.push_back("(remote) another");
831 remote_ders.push_back("(remote) chain");
832 std::unique_ptr<CertificateInfo> remote_certinfo =
833 CreateFakeCertificateAndInfoFromDers(remote_ders);
834
835 // Mock the session to return the local and remote certificates.
hbosdf6075a2016-12-19 12:58:02836 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
837 [this](const ChannelNamePairs&) {
838 std::unique_ptr<SessionStats> stats(new SessionStats());
hbos6ab97ce02016-10-03 21:16:56839 stats->transport_stats["transport"].transport_name = "transport";
hbosdf6075a2016-12-19 12:58:02840 return stats;
hbos6ab97ce02016-10-03 21:16:56841 }));
842 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
843 Invoke([this, &local_certinfo](const std::string& transport_name,
844 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
845 if (transport_name == "transport") {
846 *certificate = local_certinfo->certificate;
847 return true;
848 }
849 return false;
850 }));
851 EXPECT_CALL(test_->session(),
852 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
853 [this, &remote_certinfo](const std::string& transport_name) {
854 if (transport_name == "transport")
855 return remote_certinfo->certificate->ssl_certificate().GetReference();
856 return static_cast<rtc::SSLCertificate*>(nullptr);
857 }));
858
859 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
860 ExpectReportContainsCertificateInfo(report, *local_certinfo.get());
861 ExpectReportContainsCertificateInfo(report, *remote_certinfo.get());
862}
863
hboscc555c52016-10-18 19:48:31864TEST_F(RTCStatsCollectorTest, CollectRTCDataChannelStats) {
865 test_->data_channels().push_back(
hbosdbb64d82016-12-21 09:57:46866 new MockDataChannel(
867 0, "MockDataChannel0", DataChannelInterface::kConnecting, "udp",
868 1, 2, 3, 4));
869 RTCDataChannelStats expected_data_channel0("RTCDataChannel_0", 0);
870 expected_data_channel0.label = "MockDataChannel0";
871 expected_data_channel0.protocol = "udp";
872 expected_data_channel0.datachannelid = 0;
873 expected_data_channel0.state = "connecting";
874 expected_data_channel0.messages_sent = 1;
875 expected_data_channel0.bytes_sent = 2;
876 expected_data_channel0.messages_received = 3;
877 expected_data_channel0.bytes_received = 4;
878
hboscc555c52016-10-18 19:48:31879 test_->data_channels().push_back(
hbosdbb64d82016-12-21 09:57:46880 new MockDataChannel(
881 1, "MockDataChannel1", DataChannelInterface::kOpen, "tcp",
882 5, 6, 7, 8));
883 RTCDataChannelStats expected_data_channel1("RTCDataChannel_1", 0);
884 expected_data_channel1.label = "MockDataChannel1";
885 expected_data_channel1.protocol = "tcp";
886 expected_data_channel1.datachannelid = 1;
887 expected_data_channel1.state = "open";
888 expected_data_channel1.messages_sent = 5;
889 expected_data_channel1.bytes_sent = 6;
890 expected_data_channel1.messages_received = 7;
891 expected_data_channel1.bytes_received = 8;
892
hboscc555c52016-10-18 19:48:31893 test_->data_channels().push_back(
hbosdbb64d82016-12-21 09:57:46894 new MockDataChannel(
895 2, "MockDataChannel2", DataChannelInterface::kClosing, "udp",
896 9, 10, 11, 12));
897 RTCDataChannelStats expected_data_channel2("RTCDataChannel_2", 0);
898 expected_data_channel2.label = "MockDataChannel2";
899 expected_data_channel2.protocol = "udp";
900 expected_data_channel2.datachannelid = 2;
901 expected_data_channel2.state = "closing";
902 expected_data_channel2.messages_sent = 9;
903 expected_data_channel2.bytes_sent = 10;
904 expected_data_channel2.messages_received = 11;
905 expected_data_channel2.bytes_received = 12;
906
hboscc555c52016-10-18 19:48:31907 test_->data_channels().push_back(
hbosdbb64d82016-12-21 09:57:46908 new MockDataChannel(
909 3, "MockDataChannel3", DataChannelInterface::kClosed, "tcp",
910 13, 14, 15, 16));
911 RTCDataChannelStats expected_data_channel3("RTCDataChannel_3", 0);
912 expected_data_channel3.label = "MockDataChannel3";
913 expected_data_channel3.protocol = "tcp";
914 expected_data_channel3.datachannelid = 3;
915 expected_data_channel3.state = "closed";
916 expected_data_channel3.messages_sent = 13;
917 expected_data_channel3.bytes_sent = 14;
918 expected_data_channel3.messages_received = 15;
919 expected_data_channel3.bytes_received = 16;
hboscc555c52016-10-18 19:48:31920
921 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbosdbb64d82016-12-21 09:57:46922 ASSERT_TRUE(report->Get(expected_data_channel0.id()));
923 EXPECT_EQ(expected_data_channel0,
924 report->Get(expected_data_channel0.id())->cast_to<
925 RTCDataChannelStats>());
926 ASSERT_TRUE(report->Get(expected_data_channel1.id()));
927 EXPECT_EQ(expected_data_channel1,
928 report->Get(expected_data_channel1.id())->cast_to<
929 RTCDataChannelStats>());
930 ASSERT_TRUE(report->Get(expected_data_channel2.id()));
931 EXPECT_EQ(expected_data_channel2,
932 report->Get(expected_data_channel2.id())->cast_to<
933 RTCDataChannelStats>());
934 ASSERT_TRUE(report->Get(expected_data_channel3.id()));
935 EXPECT_EQ(expected_data_channel3,
936 report->Get(expected_data_channel3.id())->cast_to<
937 RTCDataChannelStats>());
hboscc555c52016-10-18 19:48:31938}
939
hbosab9f6e42016-10-07 09:18:47940TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
941 // Candidates in the first transport stats.
942 std::unique_ptr<cricket::Candidate> a_local_host = CreateFakeCandidate(
943 "1.2.3.4", 5,
944 "a_local_host's protocol",
945 cricket::LOCAL_PORT_TYPE,
946 0);
947 std::unique_ptr<cricket::Candidate> a_remote_srflx = CreateFakeCandidate(
948 "6.7.8.9", 10,
949 "remote_srflx's protocol",
950 cricket::STUN_PORT_TYPE,
951 1);
952 std::unique_ptr<cricket::Candidate> a_local_prflx = CreateFakeCandidate(
953 "11.12.13.14", 15,
954 "a_local_prflx's protocol",
955 cricket::PRFLX_PORT_TYPE,
956 2);
957 std::unique_ptr<cricket::Candidate> a_remote_relay = CreateFakeCandidate(
958 "16.17.18.19", 20,
959 "a_remote_relay's protocol",
960 cricket::RELAY_PORT_TYPE,
961 3);
962 // Candidates in the second transport stats.
963 std::unique_ptr<cricket::Candidate> b_local = CreateFakeCandidate(
964 "42.42.42.42", 42,
965 "b_local's protocol",
966 cricket::LOCAL_PORT_TYPE,
967 42);
968 std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
969 "42.42.42.42", 42,
970 "b_remote's protocol",
971 cricket::LOCAL_PORT_TYPE,
972 42);
973
974 SessionStats session_stats;
975
976 cricket::TransportChannelStats a_transport_channel_stats;
977 a_transport_channel_stats.connection_infos.push_back(
978 cricket::ConnectionInfo());
979 a_transport_channel_stats.connection_infos[0].local_candidate =
980 *a_local_host.get();
981 a_transport_channel_stats.connection_infos[0].remote_candidate =
982 *a_remote_srflx.get();
983 a_transport_channel_stats.connection_infos.push_back(
984 cricket::ConnectionInfo());
985 a_transport_channel_stats.connection_infos[1].local_candidate =
986 *a_local_prflx.get();
987 a_transport_channel_stats.connection_infos[1].remote_candidate =
988 *a_remote_relay.get();
hbos02d2a922016-12-21 09:29:05989 session_stats.transport_stats["a"].transport_name = "a";
hbosab9f6e42016-10-07 09:18:47990 session_stats.transport_stats["a"].channel_stats.push_back(
991 a_transport_channel_stats);
992
993 cricket::TransportChannelStats b_transport_channel_stats;
994 b_transport_channel_stats.connection_infos.push_back(
995 cricket::ConnectionInfo());
996 b_transport_channel_stats.connection_infos[0].local_candidate =
997 *b_local.get();
998 b_transport_channel_stats.connection_infos[0].remote_candidate =
999 *b_remote.get();
hbos02d2a922016-12-21 09:29:051000 session_stats.transport_stats["b"].transport_name = "b";
hbosab9f6e42016-10-07 09:18:471001 session_stats.transport_stats["b"].channel_stats.push_back(
1002 b_transport_channel_stats);
1003
1004 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 12:58:021005 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1006 [&session_stats](const ChannelNamePairs&) {
1007 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbosab9f6e42016-10-07 09:18:471008 }));
1009
1010 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1011 ExpectReportContainsCandidate(report, *a_local_host.get(), true);
1012 ExpectReportContainsCandidate(report, *a_remote_srflx.get(), false);
1013 ExpectReportContainsCandidate(report, *a_local_prflx.get(), true);
1014 ExpectReportContainsCandidate(report, *a_remote_relay.get(), false);
1015 ExpectReportContainsCandidate(report, *b_local.get(), true);
1016 ExpectReportContainsCandidate(report, *b_remote.get(), false);
1017}
1018
hbosc47a0c32016-10-11 21:54:491019TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
1020 std::unique_ptr<cricket::Candidate> local_candidate = CreateFakeCandidate(
1021 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
1022 std::unique_ptr<cricket::Candidate> remote_candidate = CreateFakeCandidate(
1023 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
1024
1025 SessionStats session_stats;
1026
1027 cricket::ConnectionInfo connection_info;
1028 connection_info.local_candidate = *local_candidate.get();
1029 connection_info.remote_candidate = *remote_candidate.get();
1030 connection_info.writable = true;
1031 connection_info.sent_total_bytes = 42;
1032 connection_info.recv_total_bytes = 1234;
1033 connection_info.rtt = 1337;
hbosd82f5122016-12-09 12:12:391034 connection_info.recv_ping_requests = 2020;
hbose448dd52016-12-12 09:22:531035 connection_info.sent_ping_requests_total = 2020;
1036 connection_info.sent_ping_requests_before_first_response = 2000;
hbosc47a0c32016-10-11 21:54:491037 connection_info.recv_ping_responses = 4321;
1038 connection_info.sent_ping_responses = 1000;
1039
1040 cricket::TransportChannelStats transport_channel_stats;
hbos0583b282016-11-30 09:50:141041 transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbosc47a0c32016-10-11 21:54:491042 transport_channel_stats.connection_infos.push_back(connection_info);
1043 session_stats.transport_stats["transport"].transport_name = "transport";
1044 session_stats.transport_stats["transport"].channel_stats.push_back(
1045 transport_channel_stats);
1046
1047 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 12:58:021048 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1049 [&session_stats](const ChannelNamePairs&) {
1050 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbosc47a0c32016-10-11 21:54:491051 }));
1052
1053 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos0583b282016-11-30 09:50:141054
1055 RTCIceCandidatePairStats expected_pair("RTCIceCandidatePair_" +
1056 local_candidate->id() + "_" +
1057 remote_candidate->id(),
1058 report->timestamp_us());
1059 expected_pair.transport_id =
1060 "RTCTransport_transport_" +
1061 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1062 expected_pair.local_candidate_id = "RTCIceCandidate_" + local_candidate->id();
1063 expected_pair.remote_candidate_id =
1064 "RTCIceCandidate_" + remote_candidate->id();
1065 expected_pair.writable = true;
1066 expected_pair.bytes_sent = 42;
1067 expected_pair.bytes_received = 1234;
hbos3168c7a2016-12-15 14:17:081068 expected_pair.current_round_trip_time = 1.337;
hbosd82f5122016-12-09 12:12:391069 expected_pair.requests_received = 2020;
hbose448dd52016-12-12 09:22:531070 expected_pair.requests_sent = 2000;
hbos0583b282016-11-30 09:50:141071 expected_pair.responses_received = 4321;
1072 expected_pair.responses_sent = 1000;
hbose448dd52016-12-12 09:22:531073 expected_pair.consent_requests_sent = (2020 - 2000);
hbos0583b282016-11-30 09:50:141074
hbosdbb64d82016-12-21 09:57:461075 ASSERT_TRUE(report->Get(expected_pair.id()));
hbos0583b282016-11-30 09:50:141076 EXPECT_EQ(
1077 expected_pair,
1078 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1079
hbosdbb64d82016-12-21 09:57:461080 ASSERT_TRUE(report->Get(*expected_pair.local_candidate_id));
hbos0583b282016-11-30 09:50:141081 ExpectReportContainsCandidate(report, connection_info.local_candidate, true);
hbosdbb64d82016-12-21 09:57:461082 ASSERT_TRUE(report->Get(*expected_pair.remote_candidate_id));
hbos0583b282016-11-30 09:50:141083 ExpectReportContainsCandidate(report, connection_info.remote_candidate,
1084 false);
hbosc47a0c32016-10-11 21:54:491085}
1086
hbosd565b732016-08-30 21:04:351087TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
hbosd565b732016-08-30 21:04:351088 {
hbos82ebe022016-11-14 09:41:091089 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1090 RTCPeerConnectionStats expected("RTCPeerConnection",
1091 report->timestamp_us());
1092 expected.data_channels_opened = 0;
1093 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 09:57:461094 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 09:41:091095 EXPECT_EQ(expected,
1096 report->Get("RTCPeerConnection")->cast_to<
1097 RTCPeerConnectionStats>());
hbosd565b732016-08-30 21:04:351098 }
1099
hbos82ebe022016-11-14 09:41:091100 rtc::scoped_refptr<DataChannel> dummy_channel_a = DataChannel::Create(
1101 nullptr, cricket::DCT_NONE, "DummyChannelA", InternalDataChannelInit());
1102 test_->pc().SignalDataChannelCreated(dummy_channel_a.get());
1103 rtc::scoped_refptr<DataChannel> dummy_channel_b = DataChannel::Create(
1104 nullptr, cricket::DCT_NONE, "DummyChannelB", InternalDataChannelInit());
1105 test_->pc().SignalDataChannelCreated(dummy_channel_b.get());
hbosd565b732016-08-30 21:04:351106
hbos82ebe022016-11-14 09:41:091107 dummy_channel_a->SignalOpened(dummy_channel_a.get());
1108 // Closing a channel that is not opened should not affect the counts.
1109 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1110
hbosd565b732016-08-30 21:04:351111 {
hbos82ebe022016-11-14 09:41:091112 collector_->ClearCachedStatsReport();
1113 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1114 RTCPeerConnectionStats expected("RTCPeerConnection",
1115 report->timestamp_us());
1116 expected.data_channels_opened = 1;
1117 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 09:57:461118 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 09:41:091119 EXPECT_EQ(expected,
1120 report->Get("RTCPeerConnection")->cast_to<
1121 RTCPeerConnectionStats>());
1122 }
1123
1124 dummy_channel_b->SignalOpened(dummy_channel_b.get());
1125 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1126
1127 {
1128 collector_->ClearCachedStatsReport();
1129 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1130 RTCPeerConnectionStats expected("RTCPeerConnection",
1131 report->timestamp_us());
1132 expected.data_channels_opened = 2;
1133 expected.data_channels_closed = 1;
hbosdbb64d82016-12-21 09:57:461134 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 09:41:091135 EXPECT_EQ(expected,
1136 report->Get("RTCPeerConnection")->cast_to<
1137 RTCPeerConnectionStats>());
hbosd565b732016-08-30 21:04:351138 }
1139}
1140
hbos09bc1282016-11-08 14:29:221141TEST_F(RTCStatsCollectorTest,
1142 CollectRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
1143 rtc::scoped_refptr<StreamCollection> local_streams =
1144 StreamCollection::Create();
1145 rtc::scoped_refptr<StreamCollection> remote_streams =
1146 StreamCollection::Create();
1147 EXPECT_CALL(test_->pc(), local_streams())
1148 .WillRepeatedly(Return(local_streams));
1149 EXPECT_CALL(test_->pc(), remote_streams())
1150 .WillRepeatedly(Return(remote_streams));
1151
1152 rtc::scoped_refptr<MediaStream> local_stream =
1153 MediaStream::Create("LocalStreamLabel");
1154 local_streams->AddStream(local_stream);
1155 rtc::scoped_refptr<MediaStream> remote_stream =
1156 MediaStream::Create("RemoteStreamLabel");
1157 remote_streams->AddStream(remote_stream);
1158
1159 // Local audio track
1160 AudioProcessorInterface::AudioProcessorStats local_audio_processor_stats;
1161 local_audio_processor_stats.echo_return_loss = 42;
1162 local_audio_processor_stats.echo_return_loss_enhancement = 52;
1163 rtc::scoped_refptr<FakeAudioTrackForStats> local_audio_track =
1164 FakeAudioTrackForStats::Create(
1165 "LocalAudioTrackID",
1166 MediaStreamTrackInterface::TrackState::kEnded,
1167 32767,
1168 new FakeAudioProcessorForStats(local_audio_processor_stats));
1169 local_stream->AddTrack(local_audio_track);
1170
1171 // Remote audio track
1172 AudioProcessorInterface::AudioProcessorStats remote_audio_processor_stats;
1173 remote_audio_processor_stats.echo_return_loss = 13;
1174 remote_audio_processor_stats.echo_return_loss_enhancement = 37;
1175 rtc::scoped_refptr<FakeAudioTrackForStats> remote_audio_track =
1176 FakeAudioTrackForStats::Create(
1177 "RemoteAudioTrackID",
1178 MediaStreamTrackInterface::TrackState::kLive,
1179 0,
1180 new FakeAudioProcessorForStats(remote_audio_processor_stats));
1181 remote_stream->AddTrack(remote_audio_track);
1182
1183 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1184
1185 RTCMediaStreamStats expected_local_stream(
hbos02d2a922016-12-21 09:29:051186 "RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 14:29:221187 expected_local_stream.stream_identifier = local_stream->label();
1188 expected_local_stream.track_ids = std::vector<std::string>();
1189 expected_local_stream.track_ids->push_back(
1190 "RTCMediaStreamTrack_LocalAudioTrackID");
hbosdbb64d82016-12-21 09:57:461191 ASSERT_TRUE(report->Get(expected_local_stream.id()));
hbos09bc1282016-11-08 14:29:221192 EXPECT_EQ(expected_local_stream,
1193 report->Get(expected_local_stream.id())->cast_to<
1194 RTCMediaStreamStats>());
1195
1196 RTCMediaStreamStats expected_remote_stream(
hbos02d2a922016-12-21 09:29:051197 "RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 14:29:221198 expected_remote_stream.stream_identifier = remote_stream->label();
1199 expected_remote_stream.track_ids = std::vector<std::string>();
1200 expected_remote_stream.track_ids->push_back(
1201 "RTCMediaStreamTrack_RemoteAudioTrackID");
hbosdbb64d82016-12-21 09:57:461202 ASSERT_TRUE(report->Get(expected_remote_stream.id()));
hbos09bc1282016-11-08 14:29:221203 EXPECT_EQ(expected_remote_stream,
1204 report->Get(expected_remote_stream.id())->cast_to<
1205 RTCMediaStreamStats>());
1206
1207 RTCMediaStreamTrackStats expected_local_audio_track(
1208 "RTCMediaStreamTrack_LocalAudioTrackID", report->timestamp_us());
1209 expected_local_audio_track.track_identifier = local_audio_track->id();
1210 expected_local_audio_track.remote_source = false;
1211 expected_local_audio_track.ended = true;
1212 expected_local_audio_track.detached = false;
1213 expected_local_audio_track.audio_level = 1.0;
1214 expected_local_audio_track.echo_return_loss = 42.0;
1215 expected_local_audio_track.echo_return_loss_enhancement = 52.0;
hbosdbb64d82016-12-21 09:57:461216 ASSERT_TRUE(report->Get(expected_local_audio_track.id()));
hbos09bc1282016-11-08 14:29:221217 EXPECT_EQ(expected_local_audio_track,
1218 report->Get(expected_local_audio_track.id())->cast_to<
1219 RTCMediaStreamTrackStats>());
1220
1221 RTCMediaStreamTrackStats expected_remote_audio_track(
1222 "RTCMediaStreamTrack_RemoteAudioTrackID", report->timestamp_us());
1223 expected_remote_audio_track.track_identifier = remote_audio_track->id();
1224 expected_remote_audio_track.remote_source = true;
1225 expected_remote_audio_track.ended = false;
1226 expected_remote_audio_track.detached = false;
1227 expected_remote_audio_track.audio_level = 0.0;
1228 expected_remote_audio_track.echo_return_loss = 13.0;
1229 expected_remote_audio_track.echo_return_loss_enhancement = 37.0;
hbosdbb64d82016-12-21 09:57:461230 ASSERT_TRUE(report->Get(expected_remote_audio_track.id()));
hbos09bc1282016-11-08 14:29:221231 EXPECT_EQ(expected_remote_audio_track,
1232 report->Get(expected_remote_audio_track.id())->cast_to<
1233 RTCMediaStreamTrackStats>());
1234}
1235
1236TEST_F(RTCStatsCollectorTest,
hbos9a394f02016-12-14 15:58:221237 CollectRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio_Defaults) {
1238 rtc::scoped_refptr<StreamCollection> local_streams =
1239 StreamCollection::Create();
1240 EXPECT_CALL(test_->pc(), local_streams())
1241 .WillRepeatedly(Return(local_streams));
1242
1243 rtc::scoped_refptr<MediaStream> local_stream =
1244 MediaStream::Create("LocalStreamLabel");
1245 local_streams->AddStream(local_stream);
1246
1247 // Local audio track
1248 AudioProcessorInterface::AudioProcessorStats local_audio_processor_stats;
1249 local_audio_processor_stats.echo_return_loss = -100;
1250 local_audio_processor_stats.echo_return_loss_enhancement = -100;
1251 rtc::scoped_refptr<FakeAudioTrackForStats> local_audio_track =
1252 FakeAudioTrackForStats::Create(
1253 "LocalAudioTrackID",
1254 MediaStreamTrackInterface::TrackState::kEnded,
1255 32767,
1256 new FakeAudioProcessorForStats(local_audio_processor_stats));
1257 local_stream->AddTrack(local_audio_track);
1258
1259 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1260
1261 RTCMediaStreamTrackStats expected_local_audio_track(
1262 "RTCMediaStreamTrack_LocalAudioTrackID", report->timestamp_us());
1263 expected_local_audio_track.track_identifier = local_audio_track->id();
1264 expected_local_audio_track.remote_source = false;
1265 expected_local_audio_track.ended = true;
1266 expected_local_audio_track.detached = false;
1267 expected_local_audio_track.audio_level = 1.0;
1268 // Should be undefined: |expected_local_audio_track.echo_return_loss| and
1269 // |expected_local_audio_track.echo_return_loss_enhancement|.
hbosdbb64d82016-12-21 09:57:461270 ASSERT_TRUE(report->Get(expected_local_audio_track.id()));
hbos9a394f02016-12-14 15:58:221271 EXPECT_EQ(expected_local_audio_track,
1272 report->Get(expected_local_audio_track.id())->cast_to<
1273 RTCMediaStreamTrackStats>());
1274}
1275
1276TEST_F(RTCStatsCollectorTest,
hbos09bc1282016-11-08 14:29:221277 CollectRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
1278 rtc::scoped_refptr<StreamCollection> local_streams =
1279 StreamCollection::Create();
1280 rtc::scoped_refptr<StreamCollection> remote_streams =
1281 StreamCollection::Create();
1282 EXPECT_CALL(test_->pc(), local_streams())
1283 .WillRepeatedly(Return(local_streams));
1284 EXPECT_CALL(test_->pc(), remote_streams())
1285 .WillRepeatedly(Return(remote_streams));
1286
1287 rtc::scoped_refptr<MediaStream> local_stream =
1288 MediaStream::Create("LocalStreamLabel");
1289 local_streams->AddStream(local_stream);
1290 rtc::scoped_refptr<MediaStream> remote_stream =
1291 MediaStream::Create("RemoteStreamLabel");
1292 remote_streams->AddStream(remote_stream);
1293
1294 // Local video track
1295 VideoTrackSourceInterface::Stats local_video_track_source_stats;
1296 local_video_track_source_stats.input_width = 1234;
1297 local_video_track_source_stats.input_height = 4321;
1298 rtc::scoped_refptr<FakeVideoTrackSourceForStats> local_video_track_source =
1299 new FakeVideoTrackSourceForStats(local_video_track_source_stats);
1300 rtc::scoped_refptr<FakeVideoTrackForStats> local_video_track =
1301 FakeVideoTrackForStats::Create(
1302 "LocalVideoTrackID",
1303 MediaStreamTrackInterface::TrackState::kLive,
1304 local_video_track_source);
1305 local_stream->AddTrack(local_video_track);
1306
1307 // Remote video track
1308 VideoTrackSourceInterface::Stats remote_video_track_source_stats;
1309 remote_video_track_source_stats.input_width = 1234;
1310 remote_video_track_source_stats.input_height = 4321;
1311 rtc::scoped_refptr<FakeVideoTrackSourceForStats> remote_video_track_source =
1312 new FakeVideoTrackSourceForStats(remote_video_track_source_stats);
1313 rtc::scoped_refptr<FakeVideoTrackForStats> remote_video_track =
1314 FakeVideoTrackForStats::Create(
1315 "RemoteVideoTrackID",
1316 MediaStreamTrackInterface::TrackState::kEnded,
1317 remote_video_track_source);
1318 remote_stream->AddTrack(remote_video_track);
1319
1320 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1321
1322 RTCMediaStreamStats expected_local_stream(
hbos02d2a922016-12-21 09:29:051323 "RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 14:29:221324 expected_local_stream.stream_identifier = local_stream->label();
1325 expected_local_stream.track_ids = std::vector<std::string>();
1326 expected_local_stream.track_ids->push_back(
1327 "RTCMediaStreamTrack_LocalVideoTrackID");
hbosdbb64d82016-12-21 09:57:461328 ASSERT_TRUE(report->Get(expected_local_stream.id()));
hbos09bc1282016-11-08 14:29:221329 EXPECT_EQ(expected_local_stream,
1330 report->Get(expected_local_stream.id())->cast_to<
1331 RTCMediaStreamStats>());
1332
1333 RTCMediaStreamStats expected_remote_stream(
hbos02d2a922016-12-21 09:29:051334 "RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
hbos09bc1282016-11-08 14:29:221335 expected_remote_stream.stream_identifier = remote_stream->label();
1336 expected_remote_stream.track_ids = std::vector<std::string>();
1337 expected_remote_stream.track_ids->push_back(
1338 "RTCMediaStreamTrack_RemoteVideoTrackID");
hbosdbb64d82016-12-21 09:57:461339 ASSERT_TRUE(report->Get(expected_remote_stream.id()));
hbos09bc1282016-11-08 14:29:221340 EXPECT_EQ(expected_remote_stream,
1341 report->Get(expected_remote_stream.id())->cast_to<
1342 RTCMediaStreamStats>());
1343
1344 RTCMediaStreamTrackStats expected_local_video_track(
1345 "RTCMediaStreamTrack_LocalVideoTrackID", report->timestamp_us());
1346 expected_local_video_track.track_identifier = local_video_track->id();
1347 expected_local_video_track.remote_source = false;
1348 expected_local_video_track.ended = false;
1349 expected_local_video_track.detached = false;
1350 expected_local_video_track.frame_width = 1234;
1351 expected_local_video_track.frame_height = 4321;
hbosdbb64d82016-12-21 09:57:461352 ASSERT_TRUE(report->Get(expected_local_video_track.id()));
hbos09bc1282016-11-08 14:29:221353 EXPECT_EQ(expected_local_video_track,
1354 report->Get(expected_local_video_track.id())->cast_to<
1355 RTCMediaStreamTrackStats>());
1356
1357 RTCMediaStreamTrackStats expected_remote_video_track(
1358 "RTCMediaStreamTrack_RemoteVideoTrackID", report->timestamp_us());
1359 expected_remote_video_track.track_identifier = remote_video_track->id();
1360 expected_remote_video_track.remote_source = true;
1361 expected_remote_video_track.ended = true;
1362 expected_remote_video_track.detached = false;
1363 expected_remote_video_track.frame_width = 1234;
1364 expected_remote_video_track.frame_height = 4321;
hbosdbb64d82016-12-21 09:57:461365 ASSERT_TRUE(report->Get(expected_remote_video_track.id()));
hbos09bc1282016-11-08 14:29:221366 EXPECT_EQ(expected_remote_video_track,
1367 report->Get(expected_remote_video_track.id())->cast_to<
1368 RTCMediaStreamTrackStats>());
1369}
1370
hboseeafe942016-11-01 10:00:171371TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
1372 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
1373 cricket::VoiceChannel voice_channel(
1374 test_->worker_thread(), test_->network_thread(), test_->media_engine(),
deadbeef7af91dd2016-12-13 19:29:111375 voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled,
1376 kDefaultSrtpRequired);
hboseeafe942016-11-01 10:00:171377
1378 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 10:32:061379
hboseeafe942016-11-01 10:00:171380 voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
1381 voice_media_info.receivers[0].local_stats.push_back(
1382 cricket::SsrcReceiverInfo());
1383 voice_media_info.receivers[0].local_stats[0].ssrc = 1;
hbos02cd4d62016-12-09 12:19:441384 voice_media_info.receivers[0].packets_lost = 42;
hboseeafe942016-11-01 10:00:171385 voice_media_info.receivers[0].packets_rcvd = 2;
1386 voice_media_info.receivers[0].bytes_rcvd = 3;
hbos0adb8282016-11-23 10:32:061387 voice_media_info.receivers[0].codec_payload_type = rtc::Optional<int>(42);
hboseeafe942016-11-01 10:00:171388 voice_media_info.receivers[0].jitter_ms = 4500;
1389 voice_media_info.receivers[0].fraction_lost = 5.5f;
hbos0adb8282016-11-23 10:32:061390
1391 RtpCodecParameters codec_parameters;
1392 codec_parameters.payload_type = 42;
1393 codec_parameters.mime_type = "dummy";
1394 codec_parameters.clock_rate = 0;
1395 voice_media_info.receive_codecs.insert(
1396 std::make_pair(codec_parameters.payload_type, codec_parameters));
1397
hboseeafe942016-11-01 10:00:171398 EXPECT_CALL(*voice_media_channel, GetStats(_))
1399 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
1400
1401 SessionStats session_stats;
1402 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
1403 session_stats.transport_stats["TransportName"].transport_name =
1404 "TransportName";
1405
1406 // Make sure the associated |RTCTransportStats| is created.
1407 cricket::TransportChannelStats channel_stats;
1408 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1409 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1410 channel_stats);
1411
hbosdf6075a2016-12-19 12:58:021412 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1413 [&session_stats](const ChannelNamePairs&) {
1414 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1415 }));
hboseeafe942016-11-01 10:00:171416 EXPECT_CALL(test_->session(), voice_channel())
1417 .WillRepeatedly(Return(&voice_channel));
1418
1419 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1420
1421 RTCInboundRTPStreamStats expected_audio(
1422 "RTCInboundRTPAudioStream_1", report->timestamp_us());
1423 expected_audio.ssrc = "1";
1424 expected_audio.is_remote = false;
1425 expected_audio.media_type = "audio";
1426 expected_audio.transport_id = "RTCTransport_TransportName_" +
1427 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 10:32:061428 expected_audio.codec_id = "RTCCodec_InboundAudio_42";
hboseeafe942016-11-01 10:00:171429 expected_audio.packets_received = 2;
1430 expected_audio.bytes_received = 3;
hbos02cd4d62016-12-09 12:19:441431 expected_audio.packets_lost = 42;
hboseeafe942016-11-01 10:00:171432 expected_audio.jitter = 4.5;
1433 expected_audio.fraction_lost = 5.5;
1434
1435 ASSERT(report->Get(expected_audio.id()));
1436 const RTCInboundRTPStreamStats& audio = report->Get(
1437 expected_audio.id())->cast_to<RTCInboundRTPStreamStats>();
1438 EXPECT_EQ(audio, expected_audio);
1439
hbosdbb64d82016-12-21 09:57:461440 ASSERT_TRUE(report->Get(*expected_audio.transport_id));
1441 ASSERT_TRUE(report->Get(*expected_audio.codec_id));
hboseeafe942016-11-01 10:00:171442}
1443
1444TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
1445 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
1446 cricket::VideoChannel video_channel(
1447 test_->worker_thread(), test_->network_thread(), video_media_channel,
deadbeef7af91dd2016-12-13 19:29:111448 nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired);
hboseeafe942016-11-01 10:00:171449
1450 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 10:32:061451
hboseeafe942016-11-01 10:00:171452 video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
1453 video_media_info.receivers[0].local_stats.push_back(
1454 cricket::SsrcReceiverInfo());
1455 video_media_info.receivers[0].local_stats[0].ssrc = 1;
1456 video_media_info.receivers[0].packets_rcvd = 2;
hbos02cd4d62016-12-09 12:19:441457 video_media_info.receivers[0].packets_lost = 42;
hboseeafe942016-11-01 10:00:171458 video_media_info.receivers[0].bytes_rcvd = 3;
1459 video_media_info.receivers[0].fraction_lost = 4.5f;
hbos0adb8282016-11-23 10:32:061460 video_media_info.receivers[0].codec_payload_type = rtc::Optional<int>(42);
hbos820f5782016-11-22 11:16:501461 video_media_info.receivers[0].firs_sent = 5;
1462 video_media_info.receivers[0].plis_sent = 6;
1463 video_media_info.receivers[0].nacks_sent = 7;
hbos0adb8282016-11-23 10:32:061464
1465 RtpCodecParameters codec_parameters;
1466 codec_parameters.payload_type = 42;
1467 codec_parameters.mime_type = "dummy";
1468 codec_parameters.clock_rate = 0;
1469 video_media_info.receive_codecs.insert(
1470 std::make_pair(codec_parameters.payload_type, codec_parameters));
1471
hboseeafe942016-11-01 10:00:171472 EXPECT_CALL(*video_media_channel, GetStats(_))
1473 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1474
1475 SessionStats session_stats;
1476 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
1477 session_stats.transport_stats["TransportName"].transport_name =
1478 "TransportName";
1479
1480 // Make sure the associated |RTCTransportStats| is created.
1481 cricket::TransportChannelStats channel_stats;
1482 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1483 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1484 channel_stats);
1485
hbosdf6075a2016-12-19 12:58:021486 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1487 [&session_stats](const ChannelNamePairs&) {
1488 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1489 }));
hboseeafe942016-11-01 10:00:171490 EXPECT_CALL(test_->session(), video_channel())
1491 .WillRepeatedly(Return(&video_channel));
1492
1493 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1494
hbos820f5782016-11-22 11:16:501495 RTCInboundRTPStreamStats expected_video(
hboseeafe942016-11-01 10:00:171496 "RTCInboundRTPVideoStream_1", report->timestamp_us());
hbos820f5782016-11-22 11:16:501497 expected_video.ssrc = "1";
1498 expected_video.is_remote = false;
1499 expected_video.media_type = "video";
1500 expected_video.transport_id = "RTCTransport_TransportName_" +
hboseeafe942016-11-01 10:00:171501 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 10:32:061502 expected_video.codec_id = "RTCCodec_InboundVideo_42";
hbos820f5782016-11-22 11:16:501503 expected_video.fir_count = 5;
1504 expected_video.pli_count = 6;
1505 expected_video.nack_count = 7;
1506 expected_video.packets_received = 2;
1507 expected_video.bytes_received = 3;
hbos02cd4d62016-12-09 12:19:441508 expected_video.packets_lost = 42;
hbos820f5782016-11-22 11:16:501509 expected_video.fraction_lost = 4.5;
hboseeafe942016-11-01 10:00:171510
hbos820f5782016-11-22 11:16:501511 ASSERT(report->Get(expected_video.id()));
1512 const RTCInboundRTPStreamStats& video = report->Get(
1513 expected_video.id())->cast_to<RTCInboundRTPStreamStats>();
1514 EXPECT_EQ(video, expected_video);
hboseeafe942016-11-01 10:00:171515
hbosdbb64d82016-12-21 09:57:461516 ASSERT_TRUE(report->Get(*expected_video.transport_id));
1517 ASSERT_TRUE(report->Get(*video.codec_id));
hboseeafe942016-11-01 10:00:171518}
1519
hbos6ded1902016-11-01 08:50:461520TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
1521 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
1522 cricket::VoiceChannel voice_channel(
1523 test_->worker_thread(), test_->network_thread(), test_->media_engine(),
deadbeef7af91dd2016-12-13 19:29:111524 voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled,
1525 kDefaultSrtpRequired);
hbos6ded1902016-11-01 08:50:461526
1527 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 10:32:061528
hbos6ded1902016-11-01 08:50:461529 voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
1530 voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1531 voice_media_info.senders[0].local_stats[0].ssrc = 1;
1532 voice_media_info.senders[0].packets_sent = 2;
1533 voice_media_info.senders[0].bytes_sent = 3;
hboseeafe942016-11-01 10:00:171534 voice_media_info.senders[0].rtt_ms = 4500;
hbos0adb8282016-11-23 10:32:061535 voice_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
1536
1537 RtpCodecParameters codec_parameters;
1538 codec_parameters.payload_type = 42;
1539 codec_parameters.mime_type = "dummy";
1540 codec_parameters.clock_rate = 0;
1541 voice_media_info.send_codecs.insert(
1542 std::make_pair(codec_parameters.payload_type, codec_parameters));
1543
hbos6ded1902016-11-01 08:50:461544 EXPECT_CALL(*voice_media_channel, GetStats(_))
1545 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
1546
1547 SessionStats session_stats;
1548 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
1549 session_stats.transport_stats["TransportName"].transport_name =
1550 "TransportName";
1551
1552 // Make sure the associated |RTCTransportStats| is created.
1553 cricket::TransportChannelStats channel_stats;
1554 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbos6ded1902016-11-01 08:50:461555 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1556 channel_stats);
1557
hbosdf6075a2016-12-19 12:58:021558 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1559 [&session_stats](const ChannelNamePairs&) {
1560 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1561 }));
hbos6ded1902016-11-01 08:50:461562 EXPECT_CALL(test_->session(), voice_channel())
1563 .WillRepeatedly(Return(&voice_channel));
1564
1565 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1566
1567 RTCOutboundRTPStreamStats expected_audio(
1568 "RTCOutboundRTPAudioStream_1", report->timestamp_us());
1569 expected_audio.ssrc = "1";
1570 expected_audio.is_remote = false;
1571 expected_audio.media_type = "audio";
1572 expected_audio.transport_id = "RTCTransport_TransportName_" +
1573 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 10:32:061574 expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
hbos6ded1902016-11-01 08:50:461575 expected_audio.packets_sent = 2;
1576 expected_audio.bytes_sent = 3;
1577 expected_audio.round_trip_time = 4.5;
1578
1579 ASSERT(report->Get(expected_audio.id()));
1580 const RTCOutboundRTPStreamStats& audio = report->Get(
1581 expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>();
1582 EXPECT_EQ(audio, expected_audio);
1583
hbosdbb64d82016-12-21 09:57:461584 ASSERT_TRUE(report->Get(*expected_audio.transport_id));
1585 ASSERT_TRUE(report->Get(*expected_audio.codec_id));
hbos6ded1902016-11-01 08:50:461586}
1587
1588TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
1589 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
1590 cricket::VideoChannel video_channel(
1591 test_->worker_thread(), test_->network_thread(), video_media_channel,
deadbeef7af91dd2016-12-13 19:29:111592 nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired);
hbos6ded1902016-11-01 08:50:461593
1594 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 10:32:061595
hbos6ded1902016-11-01 08:50:461596 video_media_info.senders.push_back(cricket::VideoSenderInfo());
1597 video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1598 video_media_info.senders[0].local_stats[0].ssrc = 1;
1599 video_media_info.senders[0].firs_rcvd = 2;
1600 video_media_info.senders[0].plis_rcvd = 3;
1601 video_media_info.senders[0].nacks_rcvd = 4;
1602 video_media_info.senders[0].packets_sent = 5;
1603 video_media_info.senders[0].bytes_sent = 6;
hboseeafe942016-11-01 10:00:171604 video_media_info.senders[0].rtt_ms = 7500;
hbos0adb8282016-11-23 10:32:061605 video_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
1606
1607 RtpCodecParameters codec_parameters;
1608 codec_parameters.payload_type = 42;
1609 codec_parameters.mime_type = "dummy";
1610 codec_parameters.clock_rate = 0;
1611 video_media_info.send_codecs.insert(
1612 std::make_pair(codec_parameters.payload_type, codec_parameters));
1613
hbos6ded1902016-11-01 08:50:461614 EXPECT_CALL(*video_media_channel, GetStats(_))
1615 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1616
1617 SessionStats session_stats;
1618 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
1619 session_stats.transport_stats["TransportName"].transport_name =
1620 "TransportName";
1621
1622 // Make sure the associated |RTCTransportStats| is created.
1623 cricket::TransportChannelStats channel_stats;
1624 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbos6ded1902016-11-01 08:50:461625 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1626 channel_stats);
1627
hbosdf6075a2016-12-19 12:58:021628 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1629 [&session_stats](const ChannelNamePairs&) {
1630 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1631 }));
hbos6ded1902016-11-01 08:50:461632 EXPECT_CALL(test_->session(), video_channel())
1633 .WillRepeatedly(Return(&video_channel));
1634
1635 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1636
1637 RTCOutboundRTPStreamStats expected_video(
1638 "RTCOutboundRTPVideoStream_1", report->timestamp_us());
1639 expected_video.ssrc = "1";
1640 expected_video.is_remote = false;
1641 expected_video.media_type = "video";
1642 expected_video.transport_id = "RTCTransport_TransportName_" +
1643 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 10:32:061644 expected_video.codec_id = "RTCCodec_OutboundVideo_42";
hbos6ded1902016-11-01 08:50:461645 expected_video.fir_count = 2;
1646 expected_video.pli_count = 3;
1647 expected_video.nack_count = 4;
1648 expected_video.packets_sent = 5;
1649 expected_video.bytes_sent = 6;
1650 expected_video.round_trip_time = 7.5;
1651
1652 ASSERT(report->Get(expected_video.id()));
1653 const RTCOutboundRTPStreamStats& video = report->Get(
1654 expected_video.id())->cast_to<RTCOutboundRTPStreamStats>();
1655 EXPECT_EQ(video, expected_video);
1656
hbosdbb64d82016-12-21 09:57:461657 ASSERT_TRUE(report->Get(*expected_video.transport_id));
1658 ASSERT_TRUE(report->Get(*expected_video.codec_id));
hbos6ded1902016-11-01 08:50:461659}
1660
hbose10e6d12016-12-15 09:54:291661TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Default) {
1662 MockVoiceMediaChannel* voice_media_channel = new MockVoiceMediaChannel();
1663 cricket::VoiceChannel voice_channel(
1664 test_->worker_thread(), test_->network_thread(), test_->media_engine(),
1665 voice_media_channel, nullptr, "VoiceContentName", kDefaultRtcpEnabled,
1666 kDefaultSrtpRequired);
1667 MockVideoMediaChannel* video_media_channel = new MockVideoMediaChannel();
1668 cricket::VideoChannel video_channel(
1669 test_->worker_thread(), test_->network_thread(), video_media_channel,
1670 nullptr, "VideoContentName", kDefaultRtcpEnabled, kDefaultSrtpRequired);
1671
1672 cricket::VoiceMediaInfo voice_media_info;
1673 voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
1674 voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1675 voice_media_info.senders[0].local_stats[0].ssrc = 1;
1676 voice_media_info.senders[0].packets_sent = 2;
1677 voice_media_info.senders[0].bytes_sent = 3;
1678 voice_media_info.senders[0].rtt_ms = -1;
1679 voice_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
1680
1681 cricket::VideoMediaInfo video_media_info;
1682 video_media_info.senders.push_back(cricket::VideoSenderInfo());
1683 video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1684 video_media_info.senders[0].local_stats[0].ssrc = 1;
1685 video_media_info.senders[0].firs_rcvd = 2;
1686 video_media_info.senders[0].plis_rcvd = 3;
1687 video_media_info.senders[0].nacks_rcvd = 4;
1688 video_media_info.senders[0].packets_sent = 5;
1689 video_media_info.senders[0].bytes_sent = 6;
1690 video_media_info.senders[0].rtt_ms = -1;
1691 video_media_info.senders[0].codec_payload_type = rtc::Optional<int>(42);
1692
1693 EXPECT_CALL(*voice_media_channel, GetStats(_))
1694 .WillOnce(DoAll(SetArgPointee<0>(voice_media_info), Return(true)));
1695 EXPECT_CALL(*video_media_channel, GetStats(_))
1696 .WillOnce(DoAll(SetArgPointee<0>(video_media_info), Return(true)));
1697
1698 SessionStats session_stats;
1699 session_stats.proxy_to_transport["VoiceContentName"] = "TransportName";
1700 session_stats.proxy_to_transport["VideoContentName"] = "TransportName";
1701 session_stats.transport_stats["TransportName"].transport_name =
1702 "TransportName";
1703
1704 // Make sure the associated |RTCTransportStats| is created.
1705 cricket::TransportChannelStats channel_stats;
1706 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1707 session_stats.transport_stats["TransportName"].channel_stats.push_back(
1708 channel_stats);
1709
hbosdf6075a2016-12-19 12:58:021710 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1711 [&session_stats](const ChannelNamePairs&) {
1712 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
1713 }));
hbose10e6d12016-12-15 09:54:291714 EXPECT_CALL(test_->session(), voice_channel())
1715 .WillRepeatedly(Return(&voice_channel));
1716 EXPECT_CALL(test_->session(), video_channel())
1717 .WillRepeatedly(Return(&video_channel));
1718
1719 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
1720
1721 RTCOutboundRTPStreamStats expected_audio(
1722 "RTCOutboundRTPAudioStream_1", report->timestamp_us());
1723 expected_audio.ssrc = "1";
1724 expected_audio.is_remote = false;
1725 expected_audio.media_type = "audio";
1726 expected_audio.transport_id = "RTCTransport_TransportName_" +
1727 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1728 expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
1729 expected_audio.packets_sent = 2;
1730 expected_audio.bytes_sent = 3;
1731 // |expected_audio.round_trip_time| should be undefined.
1732
1733 ASSERT(report->Get(expected_audio.id()));
1734 const RTCOutboundRTPStreamStats& audio = report->Get(
1735 expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>();
1736 EXPECT_EQ(audio, expected_audio);
1737
1738 RTCOutboundRTPStreamStats expected_video(
1739 "RTCOutboundRTPVideoStream_1", report->timestamp_us());
1740 expected_video.ssrc = "1";
1741 expected_video.is_remote = false;
1742 expected_video.media_type = "video";
1743 expected_video.transport_id = "RTCTransport_TransportName_" +
1744 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1745 expected_video.codec_id = "RTCCodec_OutboundVideo_42";
1746 expected_video.fir_count = 2;
1747 expected_video.pli_count = 3;
1748 expected_video.nack_count = 4;
1749 expected_video.packets_sent = 5;
1750 expected_video.bytes_sent = 6;
1751 // |expected_video.round_trip_time| should be undefined.
1752
1753 ASSERT(report->Get(expected_video.id()));
1754 const RTCOutboundRTPStreamStats& video = report->Get(
1755 expected_video.id())->cast_to<RTCOutboundRTPStreamStats>();
1756 EXPECT_EQ(video, expected_video);
1757}
1758
hbos2fa7c672016-10-24 11:00:051759TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
1760 std::unique_ptr<cricket::Candidate> rtp_local_candidate = CreateFakeCandidate(
1761 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42);
1762 std::unique_ptr<cricket::Candidate> rtp_remote_candidate =
1763 CreateFakeCandidate("42.42.42.42", 42, "protocol",
1764 cricket::LOCAL_PORT_TYPE, 42);
1765 std::unique_ptr<cricket::Candidate> rtcp_local_candidate =
1766 CreateFakeCandidate("42.42.42.42", 42, "protocol",
1767 cricket::LOCAL_PORT_TYPE, 42);
1768 std::unique_ptr<cricket::Candidate> rtcp_remote_candidate =
1769 CreateFakeCandidate("42.42.42.42", 42, "protocol",
1770 cricket::LOCAL_PORT_TYPE, 42);
1771
1772 SessionStats session_stats;
1773 session_stats.transport_stats["transport"].transport_name = "transport";
1774
1775 cricket::ConnectionInfo rtp_connection_info;
1776 rtp_connection_info.best_connection = false;
1777 rtp_connection_info.local_candidate = *rtp_local_candidate.get();
1778 rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
1779 rtp_connection_info.sent_total_bytes = 42;
1780 rtp_connection_info.recv_total_bytes = 1337;
1781 cricket::TransportChannelStats rtp_transport_channel_stats;
1782 rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1783 rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info);
1784 session_stats.transport_stats["transport"].channel_stats.push_back(
1785 rtp_transport_channel_stats);
1786
1787
1788 // Mock the session to return the desired candidates.
hbosdf6075a2016-12-19 12:58:021789 EXPECT_CALL(test_->session(), GetStats(_)).WillRepeatedly(Invoke(
1790 [&session_stats](const ChannelNamePairs&) {
1791 return std::unique_ptr<SessionStats>(new SessionStats(session_stats));
hbos2fa7c672016-10-24 11:00:051792 }));
1793
1794 // Get stats without RTCP, an active connection or certificates.
1795 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
hbos0583b282016-11-30 09:50:141796
1797 RTCTransportStats expected_rtp_transport(
1798 "RTCTransport_transport_" +
1799 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP),
1800 report->timestamp_us());
1801 expected_rtp_transport.bytes_sent = 42;
1802 expected_rtp_transport.bytes_received = 1337;
1803 expected_rtp_transport.active_connection = false;
1804
hbosdbb64d82016-12-21 09:57:461805 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 09:50:141806 EXPECT_EQ(
1807 expected_rtp_transport,
1808 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 11:00:051809
1810 cricket::ConnectionInfo rtcp_connection_info;
1811 rtcp_connection_info.best_connection = false;
1812 rtcp_connection_info.local_candidate = *rtcp_local_candidate.get();
1813 rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get();
1814 rtcp_connection_info.sent_total_bytes = 1337;
1815 rtcp_connection_info.recv_total_bytes = 42;
1816 cricket::TransportChannelStats rtcp_transport_channel_stats;
1817 rtcp_transport_channel_stats.component =
1818 cricket::ICE_CANDIDATE_COMPONENT_RTCP;
1819 rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info);
1820 session_stats.transport_stats["transport"].channel_stats.push_back(
1821 rtcp_transport_channel_stats);
1822
1823 collector_->ClearCachedStatsReport();
1824 // Get stats with RTCP and without an active connection or certificates.
1825 report = GetStatsReport();
hbos0583b282016-11-30 09:50:141826
1827 RTCTransportStats expected_rtcp_transport(
1828 "RTCTransport_transport_" +
1829 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTCP),
1830 report->timestamp_us());
1831 expected_rtcp_transport.bytes_sent = 1337;
1832 expected_rtcp_transport.bytes_received = 42;
1833 expected_rtcp_transport.active_connection = false;
1834
1835 expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
1836
hbosdbb64d82016-12-21 09:57:461837 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 09:50:141838 EXPECT_EQ(
1839 expected_rtp_transport,
1840 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 09:57:461841 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 09:50:141842 EXPECT_EQ(
1843 expected_rtcp_transport,
1844 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 11:00:051845
1846 // Get stats with an active connection.
hbos0583b282016-11-30 09:50:141847 session_stats.transport_stats["transport"]
1848 .channel_stats[1]
1849 .connection_infos[0]
1850 .best_connection = true;
hbos2fa7c672016-10-24 11:00:051851
1852 collector_->ClearCachedStatsReport();
1853 report = GetStatsReport();
hbos0583b282016-11-30 09:50:141854
1855 expected_rtcp_transport.active_connection = true;
1856 expected_rtcp_transport.selected_candidate_pair_id =
1857 "RTCIceCandidatePair_" + rtcp_local_candidate->id() + "_" +
1858 rtcp_remote_candidate->id();
1859
hbosdbb64d82016-12-21 09:57:461860 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 09:50:141861 EXPECT_EQ(
1862 expected_rtp_transport,
1863 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 09:57:461864 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 09:50:141865 EXPECT_EQ(
1866 expected_rtcp_transport,
1867 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 11:00:051868
1869 // Get stats with certificates.
1870 std::unique_ptr<CertificateInfo> local_certinfo =
1871 CreateFakeCertificateAndInfoFromDers(
1872 std::vector<std::string>({ "(local) local", "(local) chain" }));
1873 std::unique_ptr<CertificateInfo> remote_certinfo =
1874 CreateFakeCertificateAndInfoFromDers(
1875 std::vector<std::string>({ "(remote) local", "(remote) chain" }));
1876 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
1877 Invoke([this, &local_certinfo](const std::string& transport_name,
1878 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1879 if (transport_name == "transport") {
1880 *certificate = local_certinfo->certificate;
1881 return true;
1882 }
1883 return false;
1884 }));
1885 EXPECT_CALL(test_->session(),
1886 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
1887 [this, &remote_certinfo](const std::string& transport_name) {
1888 if (transport_name == "transport")
1889 return remote_certinfo->certificate->ssl_certificate().GetReference();
1890 return static_cast<rtc::SSLCertificate*>(nullptr);
1891 }));
1892
1893 collector_->ClearCachedStatsReport();
1894 report = GetStatsReport();
hbos0583b282016-11-30 09:50:141895
1896 expected_rtp_transport.local_certificate_id =
1897 "RTCCertificate_" + local_certinfo->fingerprints[0];
1898 expected_rtp_transport.remote_certificate_id =
1899 "RTCCertificate_" + remote_certinfo->fingerprints[0];
1900
1901 expected_rtcp_transport.local_certificate_id =
1902 *expected_rtp_transport.local_certificate_id;
1903 expected_rtcp_transport.remote_certificate_id =
1904 *expected_rtp_transport.remote_certificate_id;
1905
hbosdbb64d82016-12-21 09:57:461906 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 09:50:141907 EXPECT_EQ(
1908 expected_rtp_transport,
1909 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 09:57:461910 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 09:50:141911 EXPECT_EQ(
1912 expected_rtcp_transport,
1913 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 11:00:051914}
1915
hbosc82f2e12016-09-05 08:36:501916class RTCStatsCollectorTestWithFakeCollector : public testing::Test {
1917 public:
1918 RTCStatsCollectorTestWithFakeCollector()
1919 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()),
1920 collector_(FakeRTCStatsCollector::Create(
1921 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) {
1922 }
1923
1924 protected:
1925 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_;
1926 rtc::scoped_refptr<FakeRTCStatsCollector> collector_;
1927};
1928
1929TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) {
1930 collector_->VerifyThreadUsageAndResultsMerging();
1931}
1932
1933} // namespace
1934
hbosd565b732016-08-30 21:04:351935} // namespace webrtc