blob: 566d677661410e6977454e43b8ddc253336e96bd [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
hbos9e302742017-01-20 02:47:10 -080011#include <initializer_list>
hbosd565b732016-08-30 14:04:35 -070012#include <memory>
hbosda389e32016-10-25 10:55:08 -070013#include <ostream>
hbosd565b732016-08-30 14:04:35 -070014#include <string>
Steve Anton36b29d12017-10-30 09:57:42 -070015#include <utility>
hbosd565b732016-08-30 14:04:35 -070016#include <vector>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/rtpparameters.h"
19#include "api/stats/rtcstats_objects.h"
20#include "api/stats/rtcstatsreport.h"
21#include "api/test/mock_rtpreceiver.h"
22#include "api/test/mock_rtpsender.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "p2p/base/p2pconstants.h"
24#include "p2p/base/port.h"
25#include "pc/mediastream.h"
26#include "pc/mediastreamtrack.h"
Steve Anton5b387312018-02-02 16:00:20 -080027#include "pc/rtcstatscollector.h"
28#include "pc/test/fakepeerconnectionforstats.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "pc/test/mock_datachannel.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "pc/test/rtcstatsobtainer.h"
31#include "rtc_base/checks.h"
32#include "rtc_base/fakeclock.h"
33#include "rtc_base/fakesslidentity.h"
34#include "rtc_base/gunit.h"
35#include "rtc_base/logging.h"
Steve Anton5b387312018-02-02 16:00:20 -080036#include "rtc_base/ptr_util.h"
37#include "rtc_base/stringutils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "rtc_base/timedelta.h"
39#include "rtc_base/timeutils.h"
hbosd565b732016-08-30 14:04:35 -070040
hbos6ab97ce2016-10-03 14:16:56 -070041using testing::Invoke;
hbosd565b732016-08-30 14:04:35 -070042using testing::Return;
hbosd565b732016-08-30 14:04:35 -070043
44namespace webrtc {
45
hbosda389e32016-10-25 10:55:08 -070046// These are used by gtest code, such as if |EXPECT_EQ| fails.
47void PrintTo(const RTCCertificateStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070048 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070049}
50
hbos0adb8282016-11-23 02:32:06 -080051void PrintTo(const RTCCodecStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070052 *os << stats.ToJson();
hbos0adb8282016-11-23 02:32:06 -080053}
54
hbosda389e32016-10-25 10:55:08 -070055void PrintTo(const RTCDataChannelStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070056 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070057}
58
59void PrintTo(const RTCIceCandidatePairStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070060 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070061}
62
63void PrintTo(const RTCLocalIceCandidateStats& 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 RTCRemoteIceCandidateStats& 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 RTCPeerConnectionStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070072 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070073}
74
hbos09bc1282016-11-08 06:29:22 -080075void PrintTo(const RTCMediaStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070076 *os << stats.ToJson();
hbos09bc1282016-11-08 06:29:22 -080077}
78
79void PrintTo(const RTCMediaStreamTrackStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070080 *os << stats.ToJson();
hbos09bc1282016-11-08 06:29:22 -080081}
82
hboseeafe942016-11-01 03:00:17 -070083void PrintTo(const RTCInboundRTPStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070084 *os << stats.ToJson();
hboseeafe942016-11-01 03:00:17 -070085}
86
hbos6ded1902016-11-01 01:50:46 -070087void PrintTo(const RTCOutboundRTPStreamStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070088 *os << stats.ToJson();
hbos6ded1902016-11-01 01:50:46 -070089}
90
hbosda389e32016-10-25 10:55:08 -070091void PrintTo(const RTCTransportStats& stats, ::std::ostream* os) {
ehmaldonado35a872c2017-07-28 07:29:12 -070092 *os << stats.ToJson();
hbosda389e32016-10-25 10:55:08 -070093}
94
hbosc82f2e12016-09-05 01:36:50 -070095namespace {
96
97const int64_t kGetStatsReportTimeoutMs = 1000;
98
hbos6ab97ce2016-10-03 14:16:56 -070099struct CertificateInfo {
100 rtc::scoped_refptr<rtc::RTCCertificate> certificate;
101 std::vector<std::string> ders;
102 std::vector<std::string> pems;
103 std::vector<std::string> fingerprints;
104};
105
Harald Alvestranda3dab842018-01-14 09:18:58 +0100106// Return the ID for an object of the given type in a report.
107// The object must be present and be unique.
108template <typename T>
109std::string IdForType(const RTCStatsReport* report) {
110 auto stats_of_my_type = report->RTCStatsReport::GetStatsOfType<T>();
111 // We cannot use ASSERT here, since we're within a function.
112 EXPECT_EQ(1, stats_of_my_type.size())
113 << "Unexpected number of stats of this type";
114 if (stats_of_my_type.size() == 1) {
115 return stats_of_my_type[0]->id();
116 } else {
117 // Return something that is not going to be a valid stas ID.
118 return "Type not found";
119 }
120}
121
hbos6ab97ce2016-10-03 14:16:56 -0700122std::unique_ptr<CertificateInfo> CreateFakeCertificateAndInfoFromDers(
123 const std::vector<std::string>& ders) {
124 RTC_CHECK(!ders.empty());
125 std::unique_ptr<CertificateInfo> info(new CertificateInfo());
126 info->ders = ders;
127 for (const std::string& der : ders) {
128 info->pems.push_back(rtc::SSLIdentity::DerToPem(
129 "CERTIFICATE",
130 reinterpret_cast<const unsigned char*>(der.c_str()),
131 der.length()));
132 }
133 info->certificate =
134 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
135 new rtc::FakeSSLIdentity(rtc::FakeSSLCertificate(info->pems))));
136 // Strip header/footer and newline characters of PEM strings.
137 for (size_t i = 0; i < info->pems.size(); ++i) {
138 rtc::replace_substrs("-----BEGIN CERTIFICATE-----", 27,
139 "", 0, &info->pems[i]);
140 rtc::replace_substrs("-----END CERTIFICATE-----", 25,
141 "", 0, &info->pems[i]);
142 rtc::replace_substrs("\n", 1,
143 "", 0, &info->pems[i]);
144 }
145 // Fingerprint of leaf certificate.
146 std::unique_ptr<rtc::SSLFingerprint> fp(
147 rtc::SSLFingerprint::Create("sha-1",
148 &info->certificate->ssl_certificate()));
149 EXPECT_TRUE(fp);
150 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
151 // Fingerprints of the rest of the chain.
152 std::unique_ptr<rtc::SSLCertChain> chain =
153 info->certificate->ssl_certificate().GetChain();
154 if (chain) {
155 for (size_t i = 0; i < chain->GetSize(); i++) {
156 fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain->Get(i)));
157 EXPECT_TRUE(fp);
158 info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
159 }
160 }
161 EXPECT_EQ(info->ders.size(), info->fingerprints.size());
162 return info;
163}
164
hbosab9f6e42016-10-07 02:18:47 -0700165std::unique_ptr<cricket::Candidate> CreateFakeCandidate(
166 const std::string& hostname,
167 int port,
168 const std::string& protocol,
Gary Liu37e489c2017-11-21 10:49:36 -0800169 const rtc::AdapterType adapter_type,
hbosab9f6e42016-10-07 02:18:47 -0700170 const std::string& candidate_type,
171 uint32_t priority) {
172 std::unique_ptr<cricket::Candidate> candidate(new cricket::Candidate());
173 candidate->set_address(rtc::SocketAddress(hostname, port));
174 candidate->set_protocol(protocol);
Gary Liu37e489c2017-11-21 10:49:36 -0800175 candidate->set_network_type(adapter_type);
hbosab9f6e42016-10-07 02:18:47 -0700176 candidate->set_type(candidate_type);
177 candidate->set_priority(priority);
178 return candidate;
179}
180
hbos09bc1282016-11-08 06:29:22 -0800181class FakeAudioTrackForStats
182 : public MediaStreamTrack<AudioTrackInterface> {
183 public:
184 static rtc::scoped_refptr<FakeAudioTrackForStats> Create(
185 const std::string& id,
hbos9e302742017-01-20 02:47:10 -0800186 MediaStreamTrackInterface::TrackState state) {
hbos09bc1282016-11-08 06:29:22 -0800187 rtc::scoped_refptr<FakeAudioTrackForStats> audio_track_stats(
hbos9e302742017-01-20 02:47:10 -0800188 new rtc::RefCountedObject<FakeAudioTrackForStats>(id));
hbos09bc1282016-11-08 06:29:22 -0800189 audio_track_stats->set_state(state);
190 return audio_track_stats;
191 }
192
Steve Anton36b29d12017-10-30 09:57:42 -0700193 explicit FakeAudioTrackForStats(const std::string& id)
194 : MediaStreamTrack<AudioTrackInterface>(id) {}
hbos09bc1282016-11-08 06:29:22 -0800195
196 std::string kind() const override {
197 return MediaStreamTrackInterface::kAudioKind;
198 }
199 webrtc::AudioSourceInterface* GetSource() const override { return nullptr; }
200 void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
201 void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
hbos9e302742017-01-20 02:47:10 -0800202 bool GetSignalLevel(int* level) override { return false; }
hbos09bc1282016-11-08 06:29:22 -0800203 rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
hbos9e302742017-01-20 02:47:10 -0800204 return nullptr;
hbos09bc1282016-11-08 06:29:22 -0800205 }
hbos09bc1282016-11-08 06:29:22 -0800206};
207
208class FakeVideoTrackForStats
209 : public MediaStreamTrack<VideoTrackInterface> {
210 public:
211 static rtc::scoped_refptr<FakeVideoTrackForStats> Create(
212 const std::string& id,
hbos9e302742017-01-20 02:47:10 -0800213 MediaStreamTrackInterface::TrackState state) {
hbos09bc1282016-11-08 06:29:22 -0800214 rtc::scoped_refptr<FakeVideoTrackForStats> video_track(
hbos9e302742017-01-20 02:47:10 -0800215 new rtc::RefCountedObject<FakeVideoTrackForStats>(id));
hbos09bc1282016-11-08 06:29:22 -0800216 video_track->set_state(state);
217 return video_track;
218 }
219
Steve Anton36b29d12017-10-30 09:57:42 -0700220 explicit FakeVideoTrackForStats(const std::string& id)
221 : MediaStreamTrack<VideoTrackInterface>(id) {}
hbos09bc1282016-11-08 06:29:22 -0800222
223 std::string kind() const override {
224 return MediaStreamTrackInterface::kVideoKind;
225 }
perkj773be362017-07-31 23:22:01 -0700226
227 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
228 const rtc::VideoSinkWants& wants) override{};
229 void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override{};
230
hbos9e302742017-01-20 02:47:10 -0800231 VideoTrackSourceInterface* GetSource() const override { return nullptr; }
hbos09bc1282016-11-08 06:29:22 -0800232};
233
hbos84abeb12017-01-16 06:16:44 -0800234rtc::scoped_refptr<MediaStreamTrackInterface> CreateFakeTrack(
235 cricket::MediaType media_type,
hbos9e302742017-01-20 02:47:10 -0800236 const std::string& track_id,
237 MediaStreamTrackInterface::TrackState track_state) {
hbos84abeb12017-01-16 06:16:44 -0800238 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800239 return FakeAudioTrackForStats::Create(track_id, track_state);
hbos84abeb12017-01-16 06:16:44 -0800240 } else {
241 RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
hbos9e302742017-01-20 02:47:10 -0800242 return FakeVideoTrackForStats::Create(track_id, track_state);
hbos84abeb12017-01-16 06:16:44 -0800243 }
244}
245
hbos9e302742017-01-20 02:47:10 -0800246rtc::scoped_refptr<MockRtpSender> CreateMockSender(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100247 const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
Harald Alvestrandc72af932018-01-11 17:18:19 +0100248 uint32_t ssrc,
Harald Alvestranda3dab842018-01-14 09:18:58 +0100249 int attachment_id,
250 std::vector<std::string> local_stream_ids) {
hbos9e302742017-01-20 02:47:10 -0800251 rtc::scoped_refptr<MockRtpSender> sender(
252 new rtc::RefCountedObject<MockRtpSender>());
253 EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
254 EXPECT_CALL(*sender, ssrc()).WillRepeatedly(Return(ssrc));
255 EXPECT_CALL(*sender, media_type()).WillRepeatedly(Return(
256 track->kind() == MediaStreamTrackInterface::kAudioKind
257 ? cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO));
258 EXPECT_CALL(*sender, GetParameters()).WillRepeatedly(Invoke(
259 [ssrc]() {
260 RtpParameters params;
261 params.encodings.push_back(RtpEncodingParameters());
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100262 params.encodings[0].ssrc = ssrc;
hbos9e302742017-01-20 02:47:10 -0800263 return params;
264 }));
Harald Alvestrandc72af932018-01-11 17:18:19 +0100265 EXPECT_CALL(*sender, AttachmentId()).WillRepeatedly(Return(attachment_id));
Harald Alvestranda3dab842018-01-14 09:18:58 +0100266 EXPECT_CALL(*sender, stream_ids()).WillRepeatedly(Return(local_stream_ids));
hbos9e302742017-01-20 02:47:10 -0800267 return sender;
268}
269
270rtc::scoped_refptr<MockRtpReceiver> CreateMockReceiver(
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100271 const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
Harald Alvestrandc72af932018-01-11 17:18:19 +0100272 uint32_t ssrc,
273 int attachment_id) {
hbos9e302742017-01-20 02:47:10 -0800274 rtc::scoped_refptr<MockRtpReceiver> receiver(
275 new rtc::RefCountedObject<MockRtpReceiver>());
276 EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
Harald Alvestranda3dab842018-01-14 09:18:58 +0100277 EXPECT_CALL(*receiver, streams())
278 .WillRepeatedly(
279 Return(std::vector<rtc::scoped_refptr<MediaStreamInterface>>({})));
280
hbos9e302742017-01-20 02:47:10 -0800281 EXPECT_CALL(*receiver, media_type()).WillRepeatedly(Return(
282 track->kind() == MediaStreamTrackInterface::kAudioKind
283 ? cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO));
284 EXPECT_CALL(*receiver, GetParameters()).WillRepeatedly(Invoke(
285 [ssrc]() {
286 RtpParameters params;
287 params.encodings.push_back(RtpEncodingParameters());
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100288 params.encodings[0].ssrc = ssrc;
hbos9e302742017-01-20 02:47:10 -0800289 return params;
290 }));
Harald Alvestrandc72af932018-01-11 17:18:19 +0100291 EXPECT_CALL(*receiver, AttachmentId()).WillRepeatedly(Return(attachment_id));
hbos9e302742017-01-20 02:47:10 -0800292 return receiver;
293}
294
Steve Anton5b387312018-02-02 16:00:20 -0800295class RTCStatsCollectorWrapper {
hbosd565b732016-08-30 14:04:35 -0700296 public:
Steve Anton5b387312018-02-02 16:00:20 -0800297 explicit RTCStatsCollectorWrapper(
298 rtc::scoped_refptr<FakePeerConnectionForStats> pc)
299 : pc_(pc),
300 stats_collector_(
301 RTCStatsCollector::Create(pc, 50 * rtc::kNumMicrosecsPerMillisec)) {
hbosd565b732016-08-30 14:04:35 -0700302 }
303
Steve Anton5b387312018-02-02 16:00:20 -0800304 rtc::scoped_refptr<RTCStatsCollector> stats_collector() {
305 return stats_collector_;
hbosd565b732016-08-30 14:04:35 -0700306 }
307
Steve Anton5b387312018-02-02 16:00:20 -0800308 rtc::scoped_refptr<const RTCStatsReport> GetFreshStatsReport() {
309 stats_collector_->ClearCachedStatsReport();
310 return GetStatsReport();
311 }
312
313 rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() {
314 rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
315 stats_collector_->GetStatsReport(callback);
316 EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs);
317 int64_t after = rtc::TimeUTCMicros();
318 for (const RTCStats& stats : *callback->report()) {
319 EXPECT_LE(stats.timestamp_us(), after);
320 }
321 return callback->report();
hbosd565b732016-08-30 14:04:35 -0700322 }
323
hbos84abeb12017-01-16 06:16:44 -0800324 void SetupLocalTrackAndSender(cricket::MediaType media_type,
325 const std::string& track_id,
Harald Alvestrand89061872018-01-02 14:08:34 +0100326 uint32_t ssrc,
327 bool add_stream) {
Harald Alvestrand89061872018-01-02 14:08:34 +0100328 rtc::scoped_refptr<MediaStream> local_stream;
329 if (add_stream) {
330 local_stream = MediaStream::Create("LocalStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -0800331 pc_->mutable_local_streams()->AddStream(local_stream);
Harald Alvestrand89061872018-01-02 14:08:34 +0100332 }
hbos84abeb12017-01-16 06:16:44 -0800333
334 rtc::scoped_refptr<MediaStreamTrackInterface> track;
335 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800336 track = CreateFakeTrack(media_type, track_id,
337 MediaStreamTrackInterface::kLive);
Harald Alvestrand89061872018-01-02 14:08:34 +0100338 if (add_stream) {
339 local_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
340 }
hbos84abeb12017-01-16 06:16:44 -0800341 } else {
hbos9e302742017-01-20 02:47:10 -0800342 track = CreateFakeTrack(media_type, track_id,
343 MediaStreamTrackInterface::kLive);
Harald Alvestrand89061872018-01-02 14:08:34 +0100344 if (add_stream) {
345 local_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
346 }
hbos84abeb12017-01-16 06:16:44 -0800347 }
348
Harald Alvestrandc72af932018-01-11 17:18:19 +0100349 rtc::scoped_refptr<MockRtpSender> sender =
Harald Alvestranda3dab842018-01-14 09:18:58 +0100350 CreateMockSender(track, ssrc, 50, {});
Steve Anton5b387312018-02-02 16:00:20 -0800351 pc_->AddSender(sender);
hbos84abeb12017-01-16 06:16:44 -0800352 }
353
354 void SetupRemoteTrackAndReceiver(cricket::MediaType media_type,
355 const std::string& track_id,
356 uint32_t ssrc) {
hbos84abeb12017-01-16 06:16:44 -0800357 rtc::scoped_refptr<MediaStream> remote_stream =
358 MediaStream::Create("RemoteStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -0800359 pc_->mutable_remote_streams()->AddStream(remote_stream);
hbos84abeb12017-01-16 06:16:44 -0800360
361 rtc::scoped_refptr<MediaStreamTrackInterface> track;
362 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbos9e302742017-01-20 02:47:10 -0800363 track = CreateFakeTrack(media_type, track_id,
364 MediaStreamTrackInterface::kLive);
hbos84abeb12017-01-16 06:16:44 -0800365 remote_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
366 } else {
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<VideoTrackInterface*>(track.get()));
370 }
371
hbos9e302742017-01-20 02:47:10 -0800372 rtc::scoped_refptr<MockRtpReceiver> receiver =
Harald Alvestrandc72af932018-01-11 17:18:19 +0100373 CreateMockReceiver(track, ssrc, 62);
Harald Alvestranda3dab842018-01-14 09:18:58 +0100374 EXPECT_CALL(*receiver, streams())
375 .WillRepeatedly(
376 Return(std::vector<rtc::scoped_refptr<MediaStreamInterface>>(
377 {remote_stream})));
Steve Anton5b387312018-02-02 16:00:20 -0800378 pc_->AddReceiver(receiver);
hbos84abeb12017-01-16 06:16:44 -0800379 }
380
hbos9e302742017-01-20 02:47:10 -0800381 // Attaches tracks to peer connections by configuring RTP senders and RTP
382 // receivers according to the tracks' pairings with
383 // |[Voice/Video][Sender/Receiver]Info| and their SSRCs. Local tracks can be
384 // associated with multiple |[Voice/Video]SenderInfo|s, remote tracks can only
385 // be associated with one |[Voice/Video]ReceiverInfo|.
386 void CreateMockRtpSendersReceiversAndChannels(
Harald Alvestranda3dab842018-01-14 09:18:58 +0100387 std::initializer_list<
388 std::pair<MediaStreamTrackInterface*, cricket::VoiceSenderInfo>>
389 local_audio_track_info_pairs,
390 std::initializer_list<
391 std::pair<MediaStreamTrackInterface*, cricket::VoiceReceiverInfo>>
392 remote_audio_track_info_pairs,
393 std::initializer_list<
394 std::pair<MediaStreamTrackInterface*, cricket::VideoSenderInfo>>
395 local_video_track_info_pairs,
396 std::initializer_list<
397 std::pair<MediaStreamTrackInterface*, cricket::VideoReceiverInfo>>
398 remote_video_track_info_pairs,
399 std::vector<std::string> local_stream_ids,
400 std::vector<rtc::scoped_refptr<MediaStreamInterface>> remote_streams) {
Steve Anton5b387312018-02-02 16:00:20 -0800401 cricket::VoiceMediaInfo voice_media_info;
402 cricket::VideoMediaInfo video_media_info;
403
hbos9e302742017-01-20 02:47:10 -0800404 // Local audio tracks and voice sender infos
Harald Alvestrandc72af932018-01-11 17:18:19 +0100405 int attachment_id = 147;
hbos9e302742017-01-20 02:47:10 -0800406 for (auto& pair : local_audio_track_info_pairs) {
407 MediaStreamTrackInterface* local_audio_track = pair.first;
408 const cricket::VoiceSenderInfo& voice_sender_info = pair.second;
409 RTC_DCHECK_EQ(local_audio_track->kind(),
410 MediaStreamTrackInterface::kAudioKind);
411
Steve Anton5b387312018-02-02 16:00:20 -0800412 voice_media_info.senders.push_back(voice_sender_info);
Harald Alvestrandc72af932018-01-11 17:18:19 +0100413 rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
414 rtc::scoped_refptr<MediaStreamTrackInterface>(local_audio_track),
Harald Alvestranda3dab842018-01-14 09:18:58 +0100415 voice_sender_info.local_stats[0].ssrc, attachment_id++,
416 local_stream_ids);
Steve Anton5b387312018-02-02 16:00:20 -0800417 pc_->AddSender(rtp_sender);
hbos9e302742017-01-20 02:47:10 -0800418 }
Steve Anton5b387312018-02-02 16:00:20 -0800419
hbos9e302742017-01-20 02:47:10 -0800420 // Remote audio tracks and voice receiver infos
Harald Alvestrandc72af932018-01-11 17:18:19 +0100421 attachment_id = 181;
hbos9e302742017-01-20 02:47:10 -0800422 for (auto& pair : remote_audio_track_info_pairs) {
423 MediaStreamTrackInterface* remote_audio_track = pair.first;
424 const cricket::VoiceReceiverInfo& voice_receiver_info = pair.second;
425 RTC_DCHECK_EQ(remote_audio_track->kind(),
426 MediaStreamTrackInterface::kAudioKind);
427
Steve Anton5b387312018-02-02 16:00:20 -0800428 voice_media_info.receivers.push_back(voice_receiver_info);
Harald Alvestrandc72af932018-01-11 17:18:19 +0100429 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
430 rtc::scoped_refptr<MediaStreamTrackInterface>(remote_audio_track),
431 voice_receiver_info.local_stats[0].ssrc, attachment_id++);
Harald Alvestranda3dab842018-01-14 09:18:58 +0100432 EXPECT_CALL(*rtp_receiver, streams())
433 .WillRepeatedly(Return(remote_streams));
Steve Anton5b387312018-02-02 16:00:20 -0800434 pc_->AddReceiver(rtp_receiver);
hbos9e302742017-01-20 02:47:10 -0800435 }
Steve Anton5b387312018-02-02 16:00:20 -0800436
hbos9e302742017-01-20 02:47:10 -0800437 // Local video tracks and video sender infos
Harald Alvestrandc72af932018-01-11 17:18:19 +0100438 attachment_id = 151;
hbos9e302742017-01-20 02:47:10 -0800439 for (auto& pair : local_video_track_info_pairs) {
440 MediaStreamTrackInterface* local_video_track = pair.first;
441 const cricket::VideoSenderInfo& video_sender_info = pair.second;
442 RTC_DCHECK_EQ(local_video_track->kind(),
443 MediaStreamTrackInterface::kVideoKind);
444
Steve Anton5b387312018-02-02 16:00:20 -0800445 video_media_info.senders.push_back(video_sender_info);
Harald Alvestrandc72af932018-01-11 17:18:19 +0100446 rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
447 rtc::scoped_refptr<MediaStreamTrackInterface>(local_video_track),
Harald Alvestranda3dab842018-01-14 09:18:58 +0100448 video_sender_info.local_stats[0].ssrc, attachment_id++,
449 local_stream_ids);
Steve Anton5b387312018-02-02 16:00:20 -0800450 pc_->AddSender(rtp_sender);
hbos9e302742017-01-20 02:47:10 -0800451 }
Steve Anton5b387312018-02-02 16:00:20 -0800452
hbos9e302742017-01-20 02:47:10 -0800453 // Remote video tracks and video receiver infos
Harald Alvestrandc72af932018-01-11 17:18:19 +0100454 attachment_id = 191;
hbos9e302742017-01-20 02:47:10 -0800455 for (auto& pair : remote_video_track_info_pairs) {
456 MediaStreamTrackInterface* remote_video_track = pair.first;
457 const cricket::VideoReceiverInfo& video_receiver_info = pair.second;
458 RTC_DCHECK_EQ(remote_video_track->kind(),
459 MediaStreamTrackInterface::kVideoKind);
460
Steve Anton5b387312018-02-02 16:00:20 -0800461 video_media_info.receivers.push_back(video_receiver_info);
Harald Alvestrandc72af932018-01-11 17:18:19 +0100462 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
463 rtc::scoped_refptr<MediaStreamTrackInterface>(remote_video_track),
464 video_receiver_info.local_stats[0].ssrc, attachment_id++);
Harald Alvestranda3dab842018-01-14 09:18:58 +0100465 EXPECT_CALL(*rtp_receiver, streams())
466 .WillRepeatedly(Return(remote_streams));
Steve Anton5b387312018-02-02 16:00:20 -0800467 pc_->AddReceiver(rtp_receiver);
hbos9e302742017-01-20 02:47:10 -0800468 }
hbos9e302742017-01-20 02:47:10 -0800469
Steve Anton5b387312018-02-02 16:00:20 -0800470 auto* voice_media_channel = pc_->AddVoiceChannel("audio", "transport");
471 voice_media_channel->SetStats(voice_media_info);
hbos9e302742017-01-20 02:47:10 -0800472
Steve Anton5b387312018-02-02 16:00:20 -0800473 auto* video_media_channel = pc_->AddVideoChannel("video", "transport");
474 video_media_channel->SetStats(video_media_info);
hbos9e302742017-01-20 02:47:10 -0800475 }
476
hbosd565b732016-08-30 14:04:35 -0700477 private:
Steve Anton5b387312018-02-02 16:00:20 -0800478 rtc::scoped_refptr<FakePeerConnectionForStats> pc_;
479 rtc::scoped_refptr<RTCStatsCollector> stats_collector_;
hbosd565b732016-08-30 14:04:35 -0700480};
481
hbosc82f2e12016-09-05 01:36:50 -0700482class RTCStatsCollectorTest : public testing::Test {
483 public:
484 RTCStatsCollectorTest()
Steve Anton5b387312018-02-02 16:00:20 -0800485 : pc_(new rtc::RefCountedObject<FakePeerConnectionForStats>()),
486 stats_(new RTCStatsCollectorWrapper(pc_)) {}
hbosc82f2e12016-09-05 01:36:50 -0700487
hbos6ab97ce2016-10-03 14:16:56 -0700488 void ExpectReportContainsCertificateInfo(
489 const rtc::scoped_refptr<const RTCStatsReport>& report,
hbos23368e12016-12-21 04:29:17 -0800490 const CertificateInfo& certinfo) {
491 for (size_t i = 0; i < certinfo.fingerprints.size(); ++i) {
492 RTCCertificateStats expected_certificate_stats(
493 "RTCCertificate_" + certinfo.fingerprints[i],
494 report->timestamp_us());
495 expected_certificate_stats.fingerprint = certinfo.fingerprints[i];
496 expected_certificate_stats.fingerprint_algorithm = "sha-1";
497 expected_certificate_stats.base64_certificate = certinfo.pems[i];
498 if (i + 1 < certinfo.fingerprints.size()) {
499 expected_certificate_stats.issuer_certificate_id =
500 "RTCCertificate_" + certinfo.fingerprints[i + 1];
hbos6ab97ce2016-10-03 14:16:56 -0700501 }
hbos23368e12016-12-21 04:29:17 -0800502 ASSERT_TRUE(report->Get(expected_certificate_stats.id()));
503 EXPECT_EQ(expected_certificate_stats,
504 report->Get(expected_certificate_stats.id())->cast_to<
505 RTCCertificateStats>());
hbos6ab97ce2016-10-03 14:16:56 -0700506 }
507 }
508
hbosc82f2e12016-09-05 01:36:50 -0700509 protected:
Steve Anton5b387312018-02-02 16:00:20 -0800510 rtc::ScopedFakeClock fake_clock_;
511 rtc::scoped_refptr<FakePeerConnectionForStats> pc_;
512 std::unique_ptr<RTCStatsCollectorWrapper> stats_;
hbosc82f2e12016-09-05 01:36:50 -0700513};
514
515TEST_F(RTCStatsCollectorTest, SingleCallback) {
516 rtc::scoped_refptr<const RTCStatsReport> result;
Steve Anton5b387312018-02-02 16:00:20 -0800517 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&result));
hbosc82f2e12016-09-05 01:36:50 -0700518 EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs);
519}
520
521TEST_F(RTCStatsCollectorTest, MultipleCallbacks) {
Steve Anton5b387312018-02-02 16:00:20 -0800522 rtc::scoped_refptr<const RTCStatsReport> a, b, c;
523 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&a));
524 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&b));
525 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 01:36:50 -0700526 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
527 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
528 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
Steve Anton5b387312018-02-02 16:00:20 -0800529
hbosc82f2e12016-09-05 01:36:50 -0700530 EXPECT_EQ(a.get(), b.get());
531 EXPECT_EQ(b.get(), c.get());
532}
533
534TEST_F(RTCStatsCollectorTest, CachedStatsReports) {
hbosd565b732016-08-30 14:04:35 -0700535 // Caching should ensure |a| and |b| are the same report.
Steve Anton5b387312018-02-02 16:00:20 -0800536 rtc::scoped_refptr<const RTCStatsReport> a = stats_->GetStatsReport();
537 rtc::scoped_refptr<const RTCStatsReport> b = stats_->GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700538 EXPECT_EQ(a.get(), b.get());
539 // Invalidate cache by clearing it.
Steve Anton5b387312018-02-02 16:00:20 -0800540 stats_->stats_collector()->ClearCachedStatsReport();
541 rtc::scoped_refptr<const RTCStatsReport> c = stats_->GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700542 EXPECT_NE(b.get(), c.get());
543 // Invalidate cache by advancing time.
Steve Anton5b387312018-02-02 16:00:20 -0800544 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
545 rtc::scoped_refptr<const RTCStatsReport> d = stats_->GetStatsReport();
hbosd565b732016-08-30 14:04:35 -0700546 EXPECT_TRUE(d);
547 EXPECT_NE(c.get(), d.get());
548}
549
hbosc82f2e12016-09-05 01:36:50 -0700550TEST_F(RTCStatsCollectorTest, MultipleCallbacksWithInvalidatedCacheInBetween) {
Steve Anton5b387312018-02-02 16:00:20 -0800551 rtc::scoped_refptr<const RTCStatsReport> a, b, c;
552 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&a));
553 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&b));
hbosc82f2e12016-09-05 01:36:50 -0700554 // Cache is invalidated after 50 ms.
Steve Anton5b387312018-02-02 16:00:20 -0800555 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
556 stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&c));
hbosc82f2e12016-09-05 01:36:50 -0700557 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
558 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
559 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
560 EXPECT_EQ(a.get(), b.get());
561 // The act of doing |AdvanceTime| processes all messages. If this was not the
562 // case we might not require |c| to be fresher than |b|.
563 EXPECT_NE(c.get(), b.get());
564}
565
hbos6ab97ce2016-10-03 14:16:56 -0700566TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) {
Steve Anton5b387312018-02-02 16:00:20 -0800567 const char kTransportName[] = "transport";
568
569 pc_->AddVoiceChannel("audio", kTransportName);
570
hbos6ab97ce2016-10-03 14:16:56 -0700571 std::unique_ptr<CertificateInfo> local_certinfo =
572 CreateFakeCertificateAndInfoFromDers(
573 std::vector<std::string>({ "(local) single certificate" }));
Steve Anton5b387312018-02-02 16:00:20 -0800574 pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
575
hbos6ab97ce2016-10-03 14:16:56 -0700576 std::unique_ptr<CertificateInfo> remote_certinfo =
577 CreateFakeCertificateAndInfoFromDers(
578 std::vector<std::string>({ "(remote) single certificate" }));
Steve Anton5b387312018-02-02 16:00:20 -0800579 pc_->SetRemoteCertificate(
580 kTransportName,
581 remote_certinfo->certificate->ssl_certificate().GetUniqueReference());
hbos6ab97ce2016-10-03 14:16:56 -0700582
Steve Anton5b387312018-02-02 16:00:20 -0800583 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos6ab97ce2016-10-03 14:16:56 -0700584
hbos23368e12016-12-21 04:29:17 -0800585 ExpectReportContainsCertificateInfo(report, *local_certinfo);
586 ExpectReportContainsCertificateInfo(report, *remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700587}
588
hbos0adb8282016-11-23 02:32:06 -0800589TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
hbos0adb8282016-11-23 02:32:06 -0800590 // Audio
591 cricket::VoiceMediaInfo voice_media_info;
592
593 RtpCodecParameters inbound_audio_codec;
594 inbound_audio_codec.payload_type = 1;
deadbeefe702b302017-02-04 12:09:01 -0800595 inbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
596 inbound_audio_codec.name = "opus";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100597 inbound_audio_codec.clock_rate = 1337;
hbos0adb8282016-11-23 02:32:06 -0800598 voice_media_info.receive_codecs.insert(
599 std::make_pair(inbound_audio_codec.payload_type, inbound_audio_codec));
600
601 RtpCodecParameters outbound_audio_codec;
602 outbound_audio_codec.payload_type = 2;
deadbeefe702b302017-02-04 12:09:01 -0800603 outbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
604 outbound_audio_codec.name = "isac";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100605 outbound_audio_codec.clock_rate = 1338;
hbos0adb8282016-11-23 02:32:06 -0800606 voice_media_info.send_codecs.insert(
607 std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
608
Steve Anton5b387312018-02-02 16:00:20 -0800609 auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
610 voice_media_channel->SetStats(voice_media_info);
hbos0adb8282016-11-23 02:32:06 -0800611
612 // Video
613 cricket::VideoMediaInfo video_media_info;
614
615 RtpCodecParameters inbound_video_codec;
616 inbound_video_codec.payload_type = 3;
deadbeefe702b302017-02-04 12:09:01 -0800617 inbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
618 inbound_video_codec.name = "H264";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100619 inbound_video_codec.clock_rate = 1339;
hbos0adb8282016-11-23 02:32:06 -0800620 video_media_info.receive_codecs.insert(
621 std::make_pair(inbound_video_codec.payload_type, inbound_video_codec));
622
623 RtpCodecParameters outbound_video_codec;
624 outbound_video_codec.payload_type = 4;
deadbeefe702b302017-02-04 12:09:01 -0800625 outbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
626 outbound_video_codec.name = "VP8";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100627 outbound_video_codec.clock_rate = 1340;
hbos0adb8282016-11-23 02:32:06 -0800628 video_media_info.send_codecs.insert(
629 std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
630
Steve Anton5b387312018-02-02 16:00:20 -0800631 auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
632 video_media_channel->SetStats(video_media_info);
hbos0adb8282016-11-23 02:32:06 -0800633
Steve Anton5b387312018-02-02 16:00:20 -0800634 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos0adb8282016-11-23 02:32:06 -0800635
636 RTCCodecStats expected_inbound_audio_codec(
637 "RTCCodec_InboundAudio_1", report->timestamp_us());
638 expected_inbound_audio_codec.payload_type = 1;
hbos13f54b22017-02-28 06:56:04 -0800639 expected_inbound_audio_codec.mime_type = "audio/opus";
hbos0adb8282016-11-23 02:32:06 -0800640 expected_inbound_audio_codec.clock_rate = 1337;
641
642 RTCCodecStats expected_outbound_audio_codec(
643 "RTCCodec_OutboundAudio_2", report->timestamp_us());
644 expected_outbound_audio_codec.payload_type = 2;
hbos13f54b22017-02-28 06:56:04 -0800645 expected_outbound_audio_codec.mime_type = "audio/isac";
hbos0adb8282016-11-23 02:32:06 -0800646 expected_outbound_audio_codec.clock_rate = 1338;
647
648 RTCCodecStats expected_inbound_video_codec(
649 "RTCCodec_InboundVideo_3", report->timestamp_us());
650 expected_inbound_video_codec.payload_type = 3;
hbos13f54b22017-02-28 06:56:04 -0800651 expected_inbound_video_codec.mime_type = "video/H264";
hbos0adb8282016-11-23 02:32:06 -0800652 expected_inbound_video_codec.clock_rate = 1339;
653
654 RTCCodecStats expected_outbound_video_codec(
655 "RTCCodec_OutboundVideo_4", report->timestamp_us());
656 expected_outbound_video_codec.payload_type = 4;
hbos13f54b22017-02-28 06:56:04 -0800657 expected_outbound_video_codec.mime_type = "video/VP8";
hbos0adb8282016-11-23 02:32:06 -0800658 expected_outbound_video_codec.clock_rate = 1340;
659
nissec8ee8822017-01-18 07:20:55 -0800660 ASSERT_TRUE(report->Get(expected_inbound_audio_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800661 EXPECT_EQ(expected_inbound_audio_codec,
662 report->Get(expected_inbound_audio_codec.id())->cast_to<
663 RTCCodecStats>());
664
nissec8ee8822017-01-18 07:20:55 -0800665 ASSERT_TRUE(report->Get(expected_outbound_audio_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800666 EXPECT_EQ(expected_outbound_audio_codec,
667 report->Get(expected_outbound_audio_codec.id())->cast_to<
668 RTCCodecStats>());
669
nissec8ee8822017-01-18 07:20:55 -0800670 ASSERT_TRUE(report->Get(expected_inbound_video_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800671 EXPECT_EQ(expected_inbound_video_codec,
672 report->Get(expected_inbound_video_codec.id())->cast_to<
673 RTCCodecStats>());
674
nissec8ee8822017-01-18 07:20:55 -0800675 ASSERT_TRUE(report->Get(expected_outbound_video_codec.id()));
hbos0adb8282016-11-23 02:32:06 -0800676 EXPECT_EQ(expected_outbound_video_codec,
677 report->Get(expected_outbound_video_codec.id())->cast_to<
678 RTCCodecStats>());
679}
680
hbos6ab97ce2016-10-03 14:16:56 -0700681TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
Steve Anton5b387312018-02-02 16:00:20 -0800682 const char kAudioTransport[] = "audio";
683 const char kVideoTransport[] = "video";
684
685 pc_->AddVoiceChannel("audio", kAudioTransport);
hbos6ab97ce2016-10-03 14:16:56 -0700686 std::unique_ptr<CertificateInfo> audio_local_certinfo =
687 CreateFakeCertificateAndInfoFromDers(
688 std::vector<std::string>({ "(local) audio" }));
Steve Anton5b387312018-02-02 16:00:20 -0800689 pc_->SetLocalCertificate(kAudioTransport, audio_local_certinfo->certificate);
hbos6ab97ce2016-10-03 14:16:56 -0700690 std::unique_ptr<CertificateInfo> audio_remote_certinfo =
691 CreateFakeCertificateAndInfoFromDers(
692 std::vector<std::string>({ "(remote) audio" }));
Steve Anton5b387312018-02-02 16:00:20 -0800693 pc_->SetRemoteCertificate(
694 kAudioTransport, audio_remote_certinfo->certificate->ssl_certificate()
695 .GetUniqueReference());
hbos6ab97ce2016-10-03 14:16:56 -0700696
Steve Anton5b387312018-02-02 16:00:20 -0800697 pc_->AddVideoChannel("video", kVideoTransport);
hbos6ab97ce2016-10-03 14:16:56 -0700698 std::unique_ptr<CertificateInfo> video_local_certinfo =
699 CreateFakeCertificateAndInfoFromDers(
700 std::vector<std::string>({ "(local) video" }));
Steve Anton5b387312018-02-02 16:00:20 -0800701 pc_->SetLocalCertificate(kVideoTransport, video_local_certinfo->certificate);
hbos6ab97ce2016-10-03 14:16:56 -0700702 std::unique_ptr<CertificateInfo> video_remote_certinfo =
703 CreateFakeCertificateAndInfoFromDers(
704 std::vector<std::string>({ "(remote) video" }));
Steve Anton5b387312018-02-02 16:00:20 -0800705 pc_->SetRemoteCertificate(
706 kVideoTransport, video_remote_certinfo->certificate->ssl_certificate()
707 .GetUniqueReference());
hbos6ab97ce2016-10-03 14:16:56 -0700708
Steve Anton5b387312018-02-02 16:00:20 -0800709 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos23368e12016-12-21 04:29:17 -0800710 ExpectReportContainsCertificateInfo(report, *audio_local_certinfo);
711 ExpectReportContainsCertificateInfo(report, *audio_remote_certinfo);
712 ExpectReportContainsCertificateInfo(report, *video_local_certinfo);
713 ExpectReportContainsCertificateInfo(report, *video_remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700714}
715
716TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
Steve Anton5b387312018-02-02 16:00:20 -0800717 const char kTransportName[] = "transport";
718
719 pc_->AddVoiceChannel("audio", kTransportName);
720
hbos6ab97ce2016-10-03 14:16:56 -0700721 std::unique_ptr<CertificateInfo> local_certinfo =
Steve Anton5b387312018-02-02 16:00:20 -0800722 CreateFakeCertificateAndInfoFromDers(
723 {"(local) this", "(local) is", "(local) a", "(local) chain"});
724 pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
725
hbos6ab97ce2016-10-03 14:16:56 -0700726 std::unique_ptr<CertificateInfo> remote_certinfo =
Steve Anton5b387312018-02-02 16:00:20 -0800727 CreateFakeCertificateAndInfoFromDers({"(remote) this", "(remote) is",
728 "(remote) another",
729 "(remote) chain"});
730 pc_->SetRemoteCertificate(
731 kTransportName,
732 remote_certinfo->certificate->ssl_certificate().GetUniqueReference());
hbos6ab97ce2016-10-03 14:16:56 -0700733
Steve Anton5b387312018-02-02 16:00:20 -0800734 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos23368e12016-12-21 04:29:17 -0800735 ExpectReportContainsCertificateInfo(report, *local_certinfo);
736 ExpectReportContainsCertificateInfo(report, *remote_certinfo);
hbos6ab97ce2016-10-03 14:16:56 -0700737}
738
hboscc555c52016-10-18 12:48:31 -0700739TEST_F(RTCStatsCollectorTest, CollectRTCDataChannelStats) {
Steve Anton5b387312018-02-02 16:00:20 -0800740 pc_->AddSctpDataChannel(new MockDataChannel(0, "MockDataChannel0",
741 DataChannelInterface::kConnecting,
742 "udp", 1, 2, 3, 4));
hbosdbb64d82016-12-21 01:57:46 -0800743 RTCDataChannelStats expected_data_channel0("RTCDataChannel_0", 0);
744 expected_data_channel0.label = "MockDataChannel0";
745 expected_data_channel0.protocol = "udp";
746 expected_data_channel0.datachannelid = 0;
747 expected_data_channel0.state = "connecting";
748 expected_data_channel0.messages_sent = 1;
749 expected_data_channel0.bytes_sent = 2;
750 expected_data_channel0.messages_received = 3;
751 expected_data_channel0.bytes_received = 4;
752
Steve Anton5b387312018-02-02 16:00:20 -0800753 pc_->AddSctpDataChannel(new MockDataChannel(
Steve Antonbe5e2082018-01-24 15:29:17 -0800754 1, "MockDataChannel1", DataChannelInterface::kOpen, "tcp", 5, 6, 7, 8));
hbosdbb64d82016-12-21 01:57:46 -0800755 RTCDataChannelStats expected_data_channel1("RTCDataChannel_1", 0);
756 expected_data_channel1.label = "MockDataChannel1";
757 expected_data_channel1.protocol = "tcp";
758 expected_data_channel1.datachannelid = 1;
759 expected_data_channel1.state = "open";
760 expected_data_channel1.messages_sent = 5;
761 expected_data_channel1.bytes_sent = 6;
762 expected_data_channel1.messages_received = 7;
763 expected_data_channel1.bytes_received = 8;
764
Steve Anton5b387312018-02-02 16:00:20 -0800765 pc_->AddSctpDataChannel(new MockDataChannel(2, "MockDataChannel2",
766 DataChannelInterface::kClosing,
767 "udp", 9, 10, 11, 12));
hbosdbb64d82016-12-21 01:57:46 -0800768 RTCDataChannelStats expected_data_channel2("RTCDataChannel_2", 0);
769 expected_data_channel2.label = "MockDataChannel2";
770 expected_data_channel2.protocol = "udp";
771 expected_data_channel2.datachannelid = 2;
772 expected_data_channel2.state = "closing";
773 expected_data_channel2.messages_sent = 9;
774 expected_data_channel2.bytes_sent = 10;
775 expected_data_channel2.messages_received = 11;
776 expected_data_channel2.bytes_received = 12;
777
Steve Anton5b387312018-02-02 16:00:20 -0800778 pc_->AddSctpDataChannel(new MockDataChannel(3, "MockDataChannel3",
779 DataChannelInterface::kClosed,
780 "tcp", 13, 14, 15, 16));
hbosdbb64d82016-12-21 01:57:46 -0800781 RTCDataChannelStats expected_data_channel3("RTCDataChannel_3", 0);
782 expected_data_channel3.label = "MockDataChannel3";
783 expected_data_channel3.protocol = "tcp";
784 expected_data_channel3.datachannelid = 3;
785 expected_data_channel3.state = "closed";
786 expected_data_channel3.messages_sent = 13;
787 expected_data_channel3.bytes_sent = 14;
788 expected_data_channel3.messages_received = 15;
789 expected_data_channel3.bytes_received = 16;
hboscc555c52016-10-18 12:48:31 -0700790
Steve Anton5b387312018-02-02 16:00:20 -0800791 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
792
hbosdbb64d82016-12-21 01:57:46 -0800793 ASSERT_TRUE(report->Get(expected_data_channel0.id()));
794 EXPECT_EQ(expected_data_channel0,
795 report->Get(expected_data_channel0.id())->cast_to<
796 RTCDataChannelStats>());
797 ASSERT_TRUE(report->Get(expected_data_channel1.id()));
798 EXPECT_EQ(expected_data_channel1,
799 report->Get(expected_data_channel1.id())->cast_to<
800 RTCDataChannelStats>());
801 ASSERT_TRUE(report->Get(expected_data_channel2.id()));
802 EXPECT_EQ(expected_data_channel2,
803 report->Get(expected_data_channel2.id())->cast_to<
804 RTCDataChannelStats>());
805 ASSERT_TRUE(report->Get(expected_data_channel3.id()));
806 EXPECT_EQ(expected_data_channel3,
807 report->Get(expected_data_channel3.id())->cast_to<
808 RTCDataChannelStats>());
hboscc555c52016-10-18 12:48:31 -0700809}
810
hbosab9f6e42016-10-07 02:18:47 -0700811TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
812 // Candidates in the first transport stats.
Gary Liu37e489c2017-11-21 10:49:36 -0800813 std::unique_ptr<cricket::Candidate> a_local_host =
814 CreateFakeCandidate("1.2.3.4", 5, "a_local_host's protocol",
815 rtc::ADAPTER_TYPE_VPN, cricket::LOCAL_PORT_TYPE, 0);
hbosc42ba322016-12-21 03:31:45 -0800816 RTCLocalIceCandidateStats expected_a_local_host(
817 "RTCIceCandidate_" + a_local_host->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800818 expected_a_local_host.transport_id = "RTCTransport_a_0";
Gary Liu37e489c2017-11-21 10:49:36 -0800819 expected_a_local_host.network_type = "vpn";
hbosc42ba322016-12-21 03:31:45 -0800820 expected_a_local_host.ip = "1.2.3.4";
821 expected_a_local_host.port = 5;
822 expected_a_local_host.protocol = "a_local_host's protocol";
823 expected_a_local_host.candidate_type = "host";
824 expected_a_local_host.priority = 0;
hbosc3a2b7f2017-01-02 04:46:15 -0800825 EXPECT_FALSE(*expected_a_local_host.is_remote);
hbosc42ba322016-12-21 03:31:45 -0800826
hbosab9f6e42016-10-07 02:18:47 -0700827 std::unique_ptr<cricket::Candidate> a_remote_srflx = CreateFakeCandidate(
Gary Liu37e489c2017-11-21 10:49:36 -0800828 "6.7.8.9", 10, "remote_srflx's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
829 cricket::STUN_PORT_TYPE, 1);
hbosc42ba322016-12-21 03:31:45 -0800830 RTCRemoteIceCandidateStats expected_a_remote_srflx(
831 "RTCIceCandidate_" + a_remote_srflx->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800832 expected_a_remote_srflx.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -0800833 expected_a_remote_srflx.ip = "6.7.8.9";
834 expected_a_remote_srflx.port = 10;
835 expected_a_remote_srflx.protocol = "remote_srflx's protocol";
836 expected_a_remote_srflx.candidate_type = "srflx";
837 expected_a_remote_srflx.priority = 1;
hbosd17a5a72017-01-02 08:09:59 -0800838 expected_a_remote_srflx.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -0800839 EXPECT_TRUE(*expected_a_remote_srflx.is_remote);
hbosc42ba322016-12-21 03:31:45 -0800840
hbosab9f6e42016-10-07 02:18:47 -0700841 std::unique_ptr<cricket::Candidate> a_local_prflx = CreateFakeCandidate(
Gary Liu37e489c2017-11-21 10:49:36 -0800842 "11.12.13.14", 15, "a_local_prflx's protocol", rtc::ADAPTER_TYPE_CELLULAR,
843 cricket::PRFLX_PORT_TYPE, 2);
hbosc42ba322016-12-21 03:31:45 -0800844 RTCLocalIceCandidateStats expected_a_local_prflx(
845 "RTCIceCandidate_" + a_local_prflx->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800846 expected_a_local_prflx.transport_id = "RTCTransport_a_0";
Gary Liu37e489c2017-11-21 10:49:36 -0800847 expected_a_local_prflx.network_type = "cellular";
hbosc42ba322016-12-21 03:31:45 -0800848 expected_a_local_prflx.ip = "11.12.13.14";
849 expected_a_local_prflx.port = 15;
850 expected_a_local_prflx.protocol = "a_local_prflx's protocol";
851 expected_a_local_prflx.candidate_type = "prflx";
852 expected_a_local_prflx.priority = 2;
hbosd17a5a72017-01-02 08:09:59 -0800853 expected_a_local_prflx.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -0800854 EXPECT_FALSE(*expected_a_local_prflx.is_remote);
hbosc42ba322016-12-21 03:31:45 -0800855
hbosab9f6e42016-10-07 02:18:47 -0700856 std::unique_ptr<cricket::Candidate> a_remote_relay = CreateFakeCandidate(
Gary Liu37e489c2017-11-21 10:49:36 -0800857 "16.17.18.19", 20, "a_remote_relay's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
858 cricket::RELAY_PORT_TYPE, 3);
hbosc42ba322016-12-21 03:31:45 -0800859 RTCRemoteIceCandidateStats expected_a_remote_relay(
860 "RTCIceCandidate_" + a_remote_relay->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800861 expected_a_remote_relay.transport_id = "RTCTransport_a_0";
hbosc42ba322016-12-21 03:31:45 -0800862 expected_a_remote_relay.ip = "16.17.18.19";
863 expected_a_remote_relay.port = 20;
864 expected_a_remote_relay.protocol = "a_remote_relay's protocol";
865 expected_a_remote_relay.candidate_type = "relay";
866 expected_a_remote_relay.priority = 3;
hbosd17a5a72017-01-02 08:09:59 -0800867 expected_a_remote_relay.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -0800868 EXPECT_TRUE(*expected_a_remote_relay.is_remote);
hbosc42ba322016-12-21 03:31:45 -0800869
hbosab9f6e42016-10-07 02:18:47 -0700870 // Candidates in the second transport stats.
Gary Liu37e489c2017-11-21 10:49:36 -0800871 std::unique_ptr<cricket::Candidate> b_local =
872 CreateFakeCandidate("42.42.42.42", 42, "b_local's protocol",
873 rtc::ADAPTER_TYPE_WIFI, cricket::LOCAL_PORT_TYPE, 42);
hbosc42ba322016-12-21 03:31:45 -0800874 RTCLocalIceCandidateStats expected_b_local(
875 "RTCIceCandidate_" + b_local->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800876 expected_b_local.transport_id = "RTCTransport_b_0";
Gary Liu37e489c2017-11-21 10:49:36 -0800877 expected_b_local.network_type = "wifi";
hbosc42ba322016-12-21 03:31:45 -0800878 expected_b_local.ip = "42.42.42.42";
879 expected_b_local.port = 42;
880 expected_b_local.protocol = "b_local's protocol";
881 expected_b_local.candidate_type = "host";
882 expected_b_local.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -0800883 expected_b_local.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -0800884 EXPECT_FALSE(*expected_b_local.is_remote);
hbosc42ba322016-12-21 03:31:45 -0800885
hbosab9f6e42016-10-07 02:18:47 -0700886 std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
Gary Liu37e489c2017-11-21 10:49:36 -0800887 "42.42.42.42", 42, "b_remote's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
888 cricket::LOCAL_PORT_TYPE, 42);
hbosc42ba322016-12-21 03:31:45 -0800889 RTCRemoteIceCandidateStats expected_b_remote(
890 "RTCIceCandidate_" + b_remote->id(), 0);
hbosb4e426e2017-01-02 09:59:31 -0800891 expected_b_remote.transport_id = "RTCTransport_b_0";
hbosc42ba322016-12-21 03:31:45 -0800892 expected_b_remote.ip = "42.42.42.42";
893 expected_b_remote.port = 42;
894 expected_b_remote.protocol = "b_remote's protocol";
895 expected_b_remote.candidate_type = "host";
896 expected_b_remote.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -0800897 expected_b_remote.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -0800898 EXPECT_TRUE(*expected_b_remote.is_remote);
hbosab9f6e42016-10-07 02:18:47 -0700899
hbosab9f6e42016-10-07 02:18:47 -0700900 cricket::TransportChannelStats a_transport_channel_stats;
901 a_transport_channel_stats.connection_infos.push_back(
902 cricket::ConnectionInfo());
903 a_transport_channel_stats.connection_infos[0].local_candidate =
904 *a_local_host.get();
905 a_transport_channel_stats.connection_infos[0].remote_candidate =
906 *a_remote_srflx.get();
907 a_transport_channel_stats.connection_infos.push_back(
908 cricket::ConnectionInfo());
909 a_transport_channel_stats.connection_infos[1].local_candidate =
910 *a_local_prflx.get();
911 a_transport_channel_stats.connection_infos[1].remote_candidate =
912 *a_remote_relay.get();
Steve Anton5b387312018-02-02 16:00:20 -0800913
914 pc_->AddVoiceChannel("audio", "a");
915 pc_->SetTransportStats("a", a_transport_channel_stats);
hbosab9f6e42016-10-07 02:18:47 -0700916
917 cricket::TransportChannelStats b_transport_channel_stats;
918 b_transport_channel_stats.connection_infos.push_back(
919 cricket::ConnectionInfo());
920 b_transport_channel_stats.connection_infos[0].local_candidate =
921 *b_local.get();
922 b_transport_channel_stats.connection_infos[0].remote_candidate =
923 *b_remote.get();
hbosab9f6e42016-10-07 02:18:47 -0700924
Steve Anton5b387312018-02-02 16:00:20 -0800925 pc_->AddVideoChannel("video", "b");
926 pc_->SetTransportStats("b", b_transport_channel_stats);
hbosab9f6e42016-10-07 02:18:47 -0700927
Steve Anton5b387312018-02-02 16:00:20 -0800928 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbosc42ba322016-12-21 03:31:45 -0800929
hbosb4e426e2017-01-02 09:59:31 -0800930 ASSERT_TRUE(report->Get(expected_a_local_host.id()));
hbosc42ba322016-12-21 03:31:45 -0800931 EXPECT_EQ(expected_a_local_host,
932 report->Get(expected_a_local_host.id())->cast_to<
933 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800934 ASSERT_TRUE(report->Get(expected_a_remote_srflx.id()));
hbosc42ba322016-12-21 03:31:45 -0800935 EXPECT_EQ(expected_a_remote_srflx,
936 report->Get(expected_a_remote_srflx.id())->cast_to<
937 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800938 ASSERT_TRUE(report->Get(expected_a_local_prflx.id()));
hbosc42ba322016-12-21 03:31:45 -0800939 EXPECT_EQ(expected_a_local_prflx,
940 report->Get(expected_a_local_prflx.id())->cast_to<
941 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800942 ASSERT_TRUE(report->Get(expected_a_remote_relay.id()));
hbosc42ba322016-12-21 03:31:45 -0800943 EXPECT_EQ(expected_a_remote_relay,
944 report->Get(expected_a_remote_relay.id())->cast_to<
945 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800946 ASSERT_TRUE(report->Get(expected_b_local.id()));
hbosc42ba322016-12-21 03:31:45 -0800947 EXPECT_EQ(expected_b_local,
948 report->Get(expected_b_local.id())->cast_to<
949 RTCLocalIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800950 ASSERT_TRUE(report->Get(expected_b_remote.id()));
hbosc42ba322016-12-21 03:31:45 -0800951 EXPECT_EQ(expected_b_remote,
952 report->Get(expected_b_remote.id())->cast_to<
953 RTCRemoteIceCandidateStats>());
hbosb4e426e2017-01-02 09:59:31 -0800954 EXPECT_TRUE(report->Get("RTCTransport_a_0"));
955 EXPECT_TRUE(report->Get("RTCTransport_b_0"));
hbosab9f6e42016-10-07 02:18:47 -0700956}
957
hbosc47a0c32016-10-11 14:54:49 -0700958TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
Steve Anton5b387312018-02-02 16:00:20 -0800959 const char kTransportName[] = "transport";
hbos338f78a2017-02-07 06:41:21 -0800960
Gary Liu37e489c2017-11-21 10:49:36 -0800961 std::unique_ptr<cricket::Candidate> local_candidate =
962 CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
963 cricket::LOCAL_PORT_TYPE, 42);
hbosc47a0c32016-10-11 14:54:49 -0700964 std::unique_ptr<cricket::Candidate> remote_candidate = CreateFakeCandidate(
Gary Liu37e489c2017-11-21 10:49:36 -0800965 "42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_UNKNOWN,
966 cricket::LOCAL_PORT_TYPE, 42);
hbosc47a0c32016-10-11 14:54:49 -0700967
hbosc47a0c32016-10-11 14:54:49 -0700968 cricket::ConnectionInfo connection_info;
hbos338f78a2017-02-07 06:41:21 -0800969 connection_info.best_connection = false;
hbosc47a0c32016-10-11 14:54:49 -0700970 connection_info.local_candidate = *local_candidate.get();
971 connection_info.remote_candidate = *remote_candidate.get();
972 connection_info.writable = true;
973 connection_info.sent_total_bytes = 42;
974 connection_info.recv_total_bytes = 1234;
hbosbf8d3e52017-02-28 06:34:47 -0800975 connection_info.total_round_trip_time_ms = 0;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +0100976 connection_info.current_round_trip_time_ms = rtc::nullopt;
hbosd82f5122016-12-09 04:12:39 -0800977 connection_info.recv_ping_requests = 2020;
hbose448dd52016-12-12 01:22:53 -0800978 connection_info.sent_ping_requests_total = 2020;
979 connection_info.sent_ping_requests_before_first_response = 2000;
hbosc47a0c32016-10-11 14:54:49 -0700980 connection_info.recv_ping_responses = 4321;
981 connection_info.sent_ping_responses = 1000;
hbos06495bc2017-01-02 08:08:18 -0800982 connection_info.state = cricket::IceCandidatePairState::IN_PROGRESS;
983 connection_info.priority = 5555;
hbos92eaec62017-02-27 01:38:08 -0800984 connection_info.nominated = false;
hbosc47a0c32016-10-11 14:54:49 -0700985
986 cricket::TransportChannelStats transport_channel_stats;
hbos0583b282016-11-30 01:50:14 -0800987 transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
hbosc47a0c32016-10-11 14:54:49 -0700988 transport_channel_stats.connection_infos.push_back(connection_info);
hbosc47a0c32016-10-11 14:54:49 -0700989
Steve Anton5b387312018-02-02 16:00:20 -0800990 pc_->AddVideoChannel("video", kTransportName);
991 pc_->SetTransportStats(kTransportName, transport_channel_stats);
hbosc47a0c32016-10-11 14:54:49 -0700992
Steve Anton5b387312018-02-02 16:00:20 -0800993 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos0583b282016-11-30 01:50:14 -0800994
995 RTCIceCandidatePairStats expected_pair("RTCIceCandidatePair_" +
996 local_candidate->id() + "_" +
997 remote_candidate->id(),
998 report->timestamp_us());
999 expected_pair.transport_id =
1000 "RTCTransport_transport_" +
1001 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1002 expected_pair.local_candidate_id = "RTCIceCandidate_" + local_candidate->id();
1003 expected_pair.remote_candidate_id =
1004 "RTCIceCandidate_" + remote_candidate->id();
hbos06495bc2017-01-02 08:08:18 -08001005 expected_pair.state = RTCStatsIceCandidatePairState::kInProgress;
1006 expected_pair.priority = 5555;
hbos92eaec62017-02-27 01:38:08 -08001007 expected_pair.nominated = false;
hbos0583b282016-11-30 01:50:14 -08001008 expected_pair.writable = true;
1009 expected_pair.bytes_sent = 42;
1010 expected_pair.bytes_received = 1234;
hbosbf8d3e52017-02-28 06:34:47 -08001011 expected_pair.total_round_trip_time = 0.0;
hbosd82f5122016-12-09 04:12:39 -08001012 expected_pair.requests_received = 2020;
hbose448dd52016-12-12 01:22:53 -08001013 expected_pair.requests_sent = 2000;
hbos0583b282016-11-30 01:50:14 -08001014 expected_pair.responses_received = 4321;
1015 expected_pair.responses_sent = 1000;
hbose448dd52016-12-12 01:22:53 -08001016 expected_pair.consent_requests_sent = (2020 - 2000);
hbosbf8d3e52017-02-28 06:34:47 -08001017 // |expected_pair.current_round_trip_time| should be undefined because the
1018 // current RTT is not set.
hbos338f78a2017-02-07 06:41:21 -08001019 // |expected_pair.available_[outgoing/incoming]_bitrate| should be undefined
1020 // because is is not the current pair.
hbos0583b282016-11-30 01:50:14 -08001021
hbosdbb64d82016-12-21 01:57:46 -08001022 ASSERT_TRUE(report->Get(expected_pair.id()));
hbos0583b282016-11-30 01:50:14 -08001023 EXPECT_EQ(
1024 expected_pair,
1025 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
hbosb4e426e2017-01-02 09:59:31 -08001026 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
hbos0583b282016-11-30 01:50:14 -08001027
hbos92eaec62017-02-27 01:38:08 -08001028 // Set nominated and "GetStats" again.
Steve Anton5b387312018-02-02 16:00:20 -08001029 transport_channel_stats.connection_infos[0].nominated = true;
1030 pc_->SetTransportStats(kTransportName, transport_channel_stats);
1031 report = stats_->GetFreshStatsReport();
hbos92eaec62017-02-27 01:38:08 -08001032 expected_pair.nominated = true;
1033 ASSERT_TRUE(report->Get(expected_pair.id()));
1034 EXPECT_EQ(
1035 expected_pair,
1036 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1037 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1038
hbosbf8d3e52017-02-28 06:34:47 -08001039 // Set round trip times and "GetStats" again.
Steve Anton5b387312018-02-02 16:00:20 -08001040 transport_channel_stats.connection_infos[0].total_round_trip_time_ms = 7331;
1041 transport_channel_stats.connection_infos[0].current_round_trip_time_ms = 1337;
1042 pc_->SetTransportStats(kTransportName, transport_channel_stats);
1043 report = stats_->GetFreshStatsReport();
hbosbf8d3e52017-02-28 06:34:47 -08001044 expected_pair.total_round_trip_time = 7.331;
1045 expected_pair.current_round_trip_time = 1.337;
1046 ASSERT_TRUE(report->Get(expected_pair.id()));
1047 EXPECT_EQ(
1048 expected_pair,
1049 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1050 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1051
hbos338f78a2017-02-07 06:41:21 -08001052 // Make pair the current pair, clear bandwidth and "GetStats" again.
Steve Anton5b387312018-02-02 16:00:20 -08001053 transport_channel_stats.connection_infos[0].best_connection = true;
1054 pc_->SetTransportStats(kTransportName, transport_channel_stats);
1055 report = stats_->GetFreshStatsReport();
hbos338f78a2017-02-07 06:41:21 -08001056 // |expected_pair.available_[outgoing/incoming]_bitrate| should still be
1057 // undefined because bandwidth is not set.
1058 ASSERT_TRUE(report->Get(expected_pair.id()));
1059 EXPECT_EQ(
1060 expected_pair,
1061 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1062 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1063
1064 // Set bandwidth and "GetStats" again.
stefanf79ade12017-06-02 06:44:03 -07001065 webrtc::Call::Stats call_stats;
1066 const int kSendBandwidth = 888;
1067 call_stats.send_bandwidth_bps = kSendBandwidth;
1068 const int kRecvBandwidth = 999;
1069 call_stats.recv_bandwidth_bps = kRecvBandwidth;
Steve Anton5b387312018-02-02 16:00:20 -08001070 pc_->SetCallStats(call_stats);
1071 report = stats_->GetFreshStatsReport();
stefanf79ade12017-06-02 06:44:03 -07001072 expected_pair.available_outgoing_bitrate = kSendBandwidth;
1073 expected_pair.available_incoming_bitrate = kRecvBandwidth;
hbos338f78a2017-02-07 06:41:21 -08001074 ASSERT_TRUE(report->Get(expected_pair.id()));
1075 EXPECT_EQ(
1076 expected_pair,
1077 report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
1078 EXPECT_TRUE(report->Get(*expected_pair.transport_id));
1079
hbosc42ba322016-12-21 03:31:45 -08001080 RTCLocalIceCandidateStats expected_local_candidate(
1081 *expected_pair.local_candidate_id, report->timestamp_us());
hbosb4e426e2017-01-02 09:59:31 -08001082 expected_local_candidate.transport_id = *expected_pair.transport_id;
Gary Liu37e489c2017-11-21 10:49:36 -08001083 expected_local_candidate.network_type = "wifi";
hbosc42ba322016-12-21 03:31:45 -08001084 expected_local_candidate.ip = "42.42.42.42";
1085 expected_local_candidate.port = 42;
1086 expected_local_candidate.protocol = "protocol";
1087 expected_local_candidate.candidate_type = "host";
1088 expected_local_candidate.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001089 expected_local_candidate.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001090 EXPECT_FALSE(*expected_local_candidate.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001091 ASSERT_TRUE(report->Get(expected_local_candidate.id()));
1092 EXPECT_EQ(expected_local_candidate,
1093 report->Get(expected_local_candidate.id())->cast_to<
1094 RTCLocalIceCandidateStats>());
1095
1096 RTCRemoteIceCandidateStats expected_remote_candidate(
1097 *expected_pair.remote_candidate_id, report->timestamp_us());
hbosb4e426e2017-01-02 09:59:31 -08001098 expected_remote_candidate.transport_id = *expected_pair.transport_id;
hbosc42ba322016-12-21 03:31:45 -08001099 expected_remote_candidate.ip = "42.42.42.42";
1100 expected_remote_candidate.port = 42;
1101 expected_remote_candidate.protocol = "protocol";
1102 expected_remote_candidate.candidate_type = "host";
1103 expected_remote_candidate.priority = 42;
hbosd17a5a72017-01-02 08:09:59 -08001104 expected_remote_candidate.deleted = false;
hbosc3a2b7f2017-01-02 04:46:15 -08001105 EXPECT_TRUE(*expected_remote_candidate.is_remote);
hbosc42ba322016-12-21 03:31:45 -08001106 ASSERT_TRUE(report->Get(expected_remote_candidate.id()));
1107 EXPECT_EQ(expected_remote_candidate,
1108 report->Get(expected_remote_candidate.id())->cast_to<
1109 RTCRemoteIceCandidateStats>());
hbosc47a0c32016-10-11 14:54:49 -07001110}
1111
hbosd565b732016-08-30 14:04:35 -07001112TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
hbosd565b732016-08-30 14:04:35 -07001113 {
Steve Anton5b387312018-02-02 16:00:20 -08001114 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos82ebe022016-11-14 01:41:09 -08001115 RTCPeerConnectionStats expected("RTCPeerConnection",
1116 report->timestamp_us());
1117 expected.data_channels_opened = 0;
1118 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 01:57:46 -08001119 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001120 EXPECT_EQ(expected,
1121 report->Get("RTCPeerConnection")->cast_to<
1122 RTCPeerConnectionStats>());
hbosd565b732016-08-30 14:04:35 -07001123 }
1124
hbos82ebe022016-11-14 01:41:09 -08001125 rtc::scoped_refptr<DataChannel> dummy_channel_a = DataChannel::Create(
1126 nullptr, cricket::DCT_NONE, "DummyChannelA", InternalDataChannelInit());
Steve Anton5b387312018-02-02 16:00:20 -08001127 pc_->SignalDataChannelCreated()(dummy_channel_a.get());
hbos82ebe022016-11-14 01:41:09 -08001128 rtc::scoped_refptr<DataChannel> dummy_channel_b = DataChannel::Create(
1129 nullptr, cricket::DCT_NONE, "DummyChannelB", InternalDataChannelInit());
Steve Anton5b387312018-02-02 16:00:20 -08001130 pc_->SignalDataChannelCreated()(dummy_channel_b.get());
hbosd565b732016-08-30 14:04:35 -07001131
hbos82ebe022016-11-14 01:41:09 -08001132 dummy_channel_a->SignalOpened(dummy_channel_a.get());
1133 // Closing a channel that is not opened should not affect the counts.
1134 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1135
hbosd565b732016-08-30 14:04:35 -07001136 {
Steve Anton5b387312018-02-02 16:00:20 -08001137 rtc::scoped_refptr<const RTCStatsReport> report =
1138 stats_->GetFreshStatsReport();
hbos82ebe022016-11-14 01:41:09 -08001139 RTCPeerConnectionStats expected("RTCPeerConnection",
1140 report->timestamp_us());
1141 expected.data_channels_opened = 1;
1142 expected.data_channels_closed = 0;
hbosdbb64d82016-12-21 01:57:46 -08001143 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001144 EXPECT_EQ(expected,
1145 report->Get("RTCPeerConnection")->cast_to<
1146 RTCPeerConnectionStats>());
1147 }
1148
1149 dummy_channel_b->SignalOpened(dummy_channel_b.get());
1150 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1151
1152 {
Steve Anton5b387312018-02-02 16:00:20 -08001153 rtc::scoped_refptr<const RTCStatsReport> report =
1154 stats_->GetFreshStatsReport();
hbos82ebe022016-11-14 01:41:09 -08001155 RTCPeerConnectionStats expected("RTCPeerConnection",
1156 report->timestamp_us());
1157 expected.data_channels_opened = 2;
1158 expected.data_channels_closed = 1;
hbosdbb64d82016-12-21 01:57:46 -08001159 ASSERT_TRUE(report->Get("RTCPeerConnection"));
hbos82ebe022016-11-14 01:41:09 -08001160 EXPECT_EQ(expected,
1161 report->Get("RTCPeerConnection")->cast_to<
1162 RTCPeerConnectionStats>());
hbosd565b732016-08-30 14:04:35 -07001163 }
hbos5bf9def2017-03-20 03:14:14 -07001164
1165 // Re-opening a data channel (or opening a new data channel that is re-using
1166 // the same address in memory) should increase the opened count.
1167 dummy_channel_b->SignalOpened(dummy_channel_b.get());
1168
1169 {
Steve Anton5b387312018-02-02 16:00:20 -08001170 rtc::scoped_refptr<const RTCStatsReport> report =
1171 stats_->GetFreshStatsReport();
hbos5bf9def2017-03-20 03:14:14 -07001172 RTCPeerConnectionStats expected("RTCPeerConnection",
1173 report->timestamp_us());
1174 expected.data_channels_opened = 3;
1175 expected.data_channels_closed = 1;
1176 ASSERT_TRUE(report->Get("RTCPeerConnection"));
1177 EXPECT_EQ(expected,
1178 report->Get("RTCPeerConnection")->cast_to<
1179 RTCPeerConnectionStats>());
1180 }
1181
1182 dummy_channel_a->SignalClosed(dummy_channel_a.get());
1183 dummy_channel_b->SignalClosed(dummy_channel_b.get());
1184
1185 {
Steve Anton5b387312018-02-02 16:00:20 -08001186 rtc::scoped_refptr<const RTCStatsReport> report =
1187 stats_->GetFreshStatsReport();
hbos5bf9def2017-03-20 03:14:14 -07001188 RTCPeerConnectionStats expected("RTCPeerConnection",
1189 report->timestamp_us());
1190 expected.data_channels_opened = 3;
1191 expected.data_channels_closed = 3;
1192 ASSERT_TRUE(report->Get("RTCPeerConnection"));
1193 EXPECT_EQ(expected,
1194 report->Get("RTCPeerConnection")->cast_to<
1195 RTCPeerConnectionStats>());
1196 }
hbosd565b732016-08-30 14:04:35 -07001197}
1198
hbos09bc1282016-11-08 06:29:22 -08001199TEST_F(RTCStatsCollectorTest,
Harald Alvestranda3dab842018-01-14 09:18:58 +01001200 CollectLocalRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
hbos09bc1282016-11-08 06:29:22 -08001201 rtc::scoped_refptr<MediaStream> local_stream =
1202 MediaStream::Create("LocalStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -08001203 pc_->mutable_local_streams()->AddStream(local_stream);
hbos09bc1282016-11-08 06:29:22 -08001204
1205 // Local audio track
hbos9e302742017-01-20 02:47:10 -08001206 rtc::scoped_refptr<MediaStreamTrackInterface> local_audio_track =
1207 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID",
1208 MediaStreamTrackInterface::kEnded);
1209 local_stream->AddTrack(static_cast<AudioTrackInterface*>(
1210 local_audio_track.get()));
1211
1212 cricket::VoiceSenderInfo voice_sender_info_ssrc1;
1213 voice_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
1214 voice_sender_info_ssrc1.local_stats[0].ssrc = 1;
1215 voice_sender_info_ssrc1.audio_level = 32767;
zsteine76bd3a2017-07-14 12:17:49 -07001216 voice_sender_info_ssrc1.total_input_energy = 0.25;
1217 voice_sender_info_ssrc1.total_input_duration = 0.5;
Ivo Creusen56d46092017-11-24 17:29:59 +01001218 voice_sender_info_ssrc1.apm_statistics.echo_return_loss = 42.0;
1219 voice_sender_info_ssrc1.apm_statistics.echo_return_loss_enhancement = 52.0;
hbos9e302742017-01-20 02:47:10 -08001220
Steve Anton5b387312018-02-02 16:00:20 -08001221 stats_->CreateMockRtpSendersReceiversAndChannels(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001222 {std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1)}, {},
1223 {}, {}, {local_stream->label()}, {});
1224
Steve Anton5b387312018-02-02 16:00:20 -08001225 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
Harald Alvestranda3dab842018-01-14 09:18:58 +01001226
1227 RTCMediaStreamStats expected_local_stream(
1228 IdForType<RTCMediaStreamStats>(report), report->timestamp_us());
1229 expected_local_stream.stream_identifier = local_stream->label();
1230 expected_local_stream.track_ids = {
1231 IdForType<RTCMediaStreamTrackStats>(report)};
1232 ASSERT_TRUE(report->Get(expected_local_stream.id()))
1233 << "Did not find " << expected_local_stream.id() << " in "
1234 << report->ToJson();
1235 EXPECT_EQ(
1236 expected_local_stream,
1237 report->Get(expected_local_stream.id())->cast_to<RTCMediaStreamStats>());
1238
1239 RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
1240 IdForType<RTCMediaStreamTrackStats>(report), report->timestamp_us(),
1241 RTCMediaStreamTrackKind::kAudio);
1242 expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
1243 expected_local_audio_track_ssrc1.remote_source = false;
1244 expected_local_audio_track_ssrc1.ended = true;
1245 expected_local_audio_track_ssrc1.detached = false;
1246 expected_local_audio_track_ssrc1.audio_level = 1.0;
1247 expected_local_audio_track_ssrc1.total_audio_energy = 0.25;
1248 expected_local_audio_track_ssrc1.total_samples_duration = 0.5;
1249 expected_local_audio_track_ssrc1.echo_return_loss = 42.0;
1250 expected_local_audio_track_ssrc1.echo_return_loss_enhancement = 52.0;
1251 ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc1.id()))
1252 << "Did not find " << expected_local_audio_track_ssrc1.id() << " in "
1253 << report->ToJson();
1254 EXPECT_EQ(expected_local_audio_track_ssrc1,
1255 report->Get(expected_local_audio_track_ssrc1.id())
1256 ->cast_to<RTCMediaStreamTrackStats>());
1257}
1258
1259TEST_F(RTCStatsCollectorTest,
1260 CollectRemoteRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
Harald Alvestranda3dab842018-01-14 09:18:58 +01001261 rtc::scoped_refptr<MediaStream> remote_stream =
1262 MediaStream::Create("RemoteStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -08001263 pc_->mutable_remote_streams()->AddStream(remote_stream);
Harald Alvestranda3dab842018-01-14 09:18:58 +01001264
hbos09bc1282016-11-08 06:29:22 -08001265 // Remote audio track
hbos9e302742017-01-20 02:47:10 -08001266 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio_track =
1267 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID",
1268 MediaStreamTrackInterface::kLive);
1269 remote_stream->AddTrack(static_cast<AudioTrackInterface*>(
1270 remote_audio_track.get()));
1271
1272 cricket::VoiceReceiverInfo voice_receiver_info;
1273 voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo());
1274 voice_receiver_info.local_stats[0].ssrc = 3;
1275 voice_receiver_info.audio_level = 16383;
zsteine76bd3a2017-07-14 12:17:49 -07001276 voice_receiver_info.total_output_energy = 0.125;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001277 voice_receiver_info.total_samples_received = 4567;
zsteine76bd3a2017-07-14 12:17:49 -07001278 voice_receiver_info.total_output_duration = 0.25;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001279 voice_receiver_info.concealed_samples = 123;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001280 voice_receiver_info.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02001281 voice_receiver_info.jitter_buffer_delay_seconds = 3456;
hbos9e302742017-01-20 02:47:10 -08001282
Steve Anton5b387312018-02-02 16:00:20 -08001283 stats_->CreateMockRtpSendersReceiversAndChannels(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001284 {}, {std::make_pair(remote_audio_track.get(), voice_receiver_info)}, {},
1285 {}, {}, {remote_stream});
hbos09bc1282016-11-08 06:29:22 -08001286
Steve Anton5b387312018-02-02 16:00:20 -08001287 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos09bc1282016-11-08 06:29:22 -08001288
hbos09bc1282016-11-08 06:29:22 -08001289 RTCMediaStreamStats expected_remote_stream(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001290 IdForType<RTCMediaStreamStats>(report), report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001291 expected_remote_stream.stream_identifier = remote_stream->label();
Harald Alvestranda3dab842018-01-14 09:18:58 +01001292 expected_remote_stream.track_ids =
1293 std::vector<std::string>({IdForType<RTCMediaStreamTrackStats>(report)});
1294 ASSERT_TRUE(report->Get(expected_remote_stream.id()))
1295 << "Did not find " << expected_remote_stream.id() << " in "
1296 << report->ToJson();
hbos09bc1282016-11-08 06:29:22 -08001297 EXPECT_EQ(expected_remote_stream,
1298 report->Get(expected_remote_stream.id())->cast_to<
1299 RTCMediaStreamStats>());
1300
hbos09bc1282016-11-08 06:29:22 -08001301 RTCMediaStreamTrackStats expected_remote_audio_track(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001302 IdForType<RTCMediaStreamTrackStats>(report), report->timestamp_us(),
1303 RTCMediaStreamTrackKind::kAudio);
hbos09bc1282016-11-08 06:29:22 -08001304 expected_remote_audio_track.track_identifier = remote_audio_track->id();
1305 expected_remote_audio_track.remote_source = true;
1306 expected_remote_audio_track.ended = false;
1307 expected_remote_audio_track.detached = false;
hbos9e302742017-01-20 02:47:10 -08001308 expected_remote_audio_track.audio_level = 16383.0 / 32767.0;
zsteine76bd3a2017-07-14 12:17:49 -07001309 expected_remote_audio_track.total_audio_energy = 0.125;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001310 expected_remote_audio_track.total_samples_received = 4567;
zsteine76bd3a2017-07-14 12:17:49 -07001311 expected_remote_audio_track.total_samples_duration = 0.25;
Steve Anton2dbc69f2017-08-24 17:15:13 -07001312 expected_remote_audio_track.concealed_samples = 123;
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +02001313 expected_remote_audio_track.concealment_events = 12;
Gustaf Ullbergb0a02072017-10-02 12:00:34 +02001314 expected_remote_audio_track.jitter_buffer_delay = 3456;
hbosdbb64d82016-12-21 01:57:46 -08001315 ASSERT_TRUE(report->Get(expected_remote_audio_track.id()));
hbos09bc1282016-11-08 06:29:22 -08001316 EXPECT_EQ(expected_remote_audio_track,
1317 report->Get(expected_remote_audio_track.id())->cast_to<
1318 RTCMediaStreamTrackStats>());
1319}
1320
1321TEST_F(RTCStatsCollectorTest,
Harald Alvestranda3dab842018-01-14 09:18:58 +01001322 CollectLocalRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
hbos09bc1282016-11-08 06:29:22 -08001323 rtc::scoped_refptr<MediaStream> local_stream =
1324 MediaStream::Create("LocalStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -08001325 pc_->mutable_local_streams()->AddStream(local_stream);
hbos09bc1282016-11-08 06:29:22 -08001326
1327 // Local video track
hbos9e302742017-01-20 02:47:10 -08001328 rtc::scoped_refptr<MediaStreamTrackInterface> local_video_track =
1329 CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID",
1330 MediaStreamTrackInterface::kLive);
1331 local_stream->AddTrack(static_cast<VideoTrackInterface*>(
1332 local_video_track.get()));
hbos09bc1282016-11-08 06:29:22 -08001333
hbos9e302742017-01-20 02:47:10 -08001334 cricket::VideoSenderInfo video_sender_info_ssrc1;
1335 video_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
1336 video_sender_info_ssrc1.local_stats[0].ssrc = 1;
1337 video_sender_info_ssrc1.send_frame_width = 1234;
1338 video_sender_info_ssrc1.send_frame_height = 4321;
hbosfefe0762017-01-20 06:14:25 -08001339 video_sender_info_ssrc1.frames_encoded = 11;
hbos9e302742017-01-20 02:47:10 -08001340
Steve Anton5b387312018-02-02 16:00:20 -08001341 stats_->CreateMockRtpSendersReceiversAndChannels(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001342 {}, {},
1343 {std::make_pair(local_video_track.get(), video_sender_info_ssrc1)}, {},
1344 {local_stream->label()}, {});
1345
Steve Anton5b387312018-02-02 16:00:20 -08001346 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
Harald Alvestranda3dab842018-01-14 09:18:58 +01001347
1348 auto stats_of_my_type = report->GetStatsOfType<RTCMediaStreamStats>();
1349 ASSERT_EQ(1, stats_of_my_type.size()) << "No stream in " << report->ToJson();
1350 auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
1351 ASSERT_EQ(1, stats_of_track_type.size())
1352 << "Wrong number of tracks in " << report->ToJson();
1353
1354 RTCMediaStreamStats expected_local_stream(stats_of_my_type[0]->id(),
1355 report->timestamp_us());
1356 expected_local_stream.stream_identifier = local_stream->label();
1357 expected_local_stream.track_ids =
1358 std::vector<std::string>({stats_of_track_type[0]->id()});
1359 ASSERT_TRUE(report->Get(expected_local_stream.id()));
1360 EXPECT_EQ(
1361 expected_local_stream,
1362 report->Get(expected_local_stream.id())->cast_to<RTCMediaStreamStats>());
1363
1364 RTCMediaStreamTrackStats expected_local_video_track_ssrc1(
1365 stats_of_track_type[0]->id(), report->timestamp_us(),
1366 RTCMediaStreamTrackKind::kVideo);
1367 expected_local_video_track_ssrc1.track_identifier = local_video_track->id();
1368 expected_local_video_track_ssrc1.remote_source = false;
1369 expected_local_video_track_ssrc1.ended = false;
1370 expected_local_video_track_ssrc1.detached = false;
1371 expected_local_video_track_ssrc1.frame_width = 1234;
1372 expected_local_video_track_ssrc1.frame_height = 4321;
1373 expected_local_video_track_ssrc1.frames_sent = 11;
1374 ASSERT_TRUE(report->Get(expected_local_video_track_ssrc1.id()));
1375 EXPECT_EQ(expected_local_video_track_ssrc1,
1376 report->Get(expected_local_video_track_ssrc1.id())
1377 ->cast_to<RTCMediaStreamTrackStats>());
1378}
1379
1380TEST_F(RTCStatsCollectorTest,
1381 CollectRemoteRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
Harald Alvestranda3dab842018-01-14 09:18:58 +01001382 rtc::scoped_refptr<MediaStream> remote_stream =
1383 MediaStream::Create("RemoteStreamLabel");
Steve Anton5b387312018-02-02 16:00:20 -08001384 pc_->mutable_remote_streams()->AddStream(remote_stream);
Harald Alvestranda3dab842018-01-14 09:18:58 +01001385
hbos9e302742017-01-20 02:47:10 -08001386 // Remote video track with values
1387 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc3 =
1388 CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID3",
1389 MediaStreamTrackInterface::kEnded);
1390 remote_stream->AddTrack(static_cast<VideoTrackInterface*>(
1391 remote_video_track_ssrc3.get()));
1392
1393 cricket::VideoReceiverInfo video_receiver_info_ssrc3;
1394 video_receiver_info_ssrc3.local_stats.push_back(cricket::SsrcReceiverInfo());
1395 video_receiver_info_ssrc3.local_stats[0].ssrc = 3;
1396 video_receiver_info_ssrc3.frame_width = 6789;
1397 video_receiver_info_ssrc3.frame_height = 9876;
hbos50cfe1f2017-01-23 07:21:55 -08001398 video_receiver_info_ssrc3.frames_received = 1000;
1399 video_receiver_info_ssrc3.frames_decoded = 995;
1400 video_receiver_info_ssrc3.frames_rendered = 990;
hbos9e302742017-01-20 02:47:10 -08001401
Steve Anton5b387312018-02-02 16:00:20 -08001402 stats_->CreateMockRtpSendersReceiversAndChannels(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001403 {}, {}, {},
Harald Alvestrandc72af932018-01-11 17:18:19 +01001404 {std::make_pair(remote_video_track_ssrc3.get(),
Harald Alvestranda3dab842018-01-14 09:18:58 +01001405 video_receiver_info_ssrc3)},
1406 {}, {remote_stream});
hbos09bc1282016-11-08 06:29:22 -08001407
Steve Anton5b387312018-02-02 16:00:20 -08001408 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos09bc1282016-11-08 06:29:22 -08001409
Harald Alvestranda3dab842018-01-14 09:18:58 +01001410 auto stats_of_my_type = report->GetStatsOfType<RTCMediaStreamStats>();
1411 ASSERT_EQ(1, stats_of_my_type.size()) << "No stream in " << report->ToJson();
1412 auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
1413 ASSERT_EQ(1, stats_of_track_type.size())
1414 << "Wrong number of tracks in " << report->ToJson();
1415 ASSERT_TRUE(*(stats_of_track_type[0]->remote_source));
hbos09bc1282016-11-08 06:29:22 -08001416
Harald Alvestranda3dab842018-01-14 09:18:58 +01001417 RTCMediaStreamStats expected_remote_stream(stats_of_my_type[0]->id(),
1418 report->timestamp_us());
hbos09bc1282016-11-08 06:29:22 -08001419 expected_remote_stream.stream_identifier = remote_stream->label();
Harald Alvestranda3dab842018-01-14 09:18:58 +01001420 expected_remote_stream.track_ids =
1421 std::vector<std::string>({stats_of_track_type[0]->id()});
hbosdbb64d82016-12-21 01:57:46 -08001422 ASSERT_TRUE(report->Get(expected_remote_stream.id()));
hbos09bc1282016-11-08 06:29:22 -08001423 EXPECT_EQ(expected_remote_stream,
1424 report->Get(expected_remote_stream.id())->cast_to<
1425 RTCMediaStreamStats>());
1426
hbos9e302742017-01-20 02:47:10 -08001427 RTCMediaStreamTrackStats expected_remote_video_track_ssrc3(
Harald Alvestranda3dab842018-01-14 09:18:58 +01001428 stats_of_track_type[0]->id(), report->timestamp_us(),
1429 RTCMediaStreamTrackKind::kVideo);
hbos9e302742017-01-20 02:47:10 -08001430 expected_remote_video_track_ssrc3.track_identifier =
1431 remote_video_track_ssrc3->id();
1432 expected_remote_video_track_ssrc3.remote_source = true;
1433 expected_remote_video_track_ssrc3.ended = true;
1434 expected_remote_video_track_ssrc3.detached = false;
1435 expected_remote_video_track_ssrc3.frame_width = 6789;
1436 expected_remote_video_track_ssrc3.frame_height = 9876;
hbos50cfe1f2017-01-23 07:21:55 -08001437 expected_remote_video_track_ssrc3.frames_received = 1000;
1438 expected_remote_video_track_ssrc3.frames_decoded = 995;
1439 expected_remote_video_track_ssrc3.frames_dropped = 1000 - 990;
hbos9e302742017-01-20 02:47:10 -08001440 ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc3.id()));
1441 EXPECT_EQ(expected_remote_video_track_ssrc3,
1442 report->Get(expected_remote_video_track_ssrc3.id())->cast_to<
1443 RTCMediaStreamTrackStats>());
hbos09bc1282016-11-08 06:29:22 -08001444}
1445
hboseeafe942016-11-01 03:00:17 -07001446TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
Steve Anton5b387312018-02-02 16:00:20 -08001447 const char kTransportName[] = "TransportName";
hbos84abeb12017-01-16 06:16:44 -08001448
hboseeafe942016-11-01 03:00:17 -07001449 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 02:32:06 -08001450
hboseeafe942016-11-01 03:00:17 -07001451 voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
1452 voice_media_info.receivers[0].local_stats.push_back(
1453 cricket::SsrcReceiverInfo());
1454 voice_media_info.receivers[0].local_stats[0].ssrc = 1;
Harald Alvestrand719487e2017-12-13 12:26:04 +01001455 voice_media_info.receivers[0].packets_lost = -1; // Signed per RFC3550
hboseeafe942016-11-01 03:00:17 -07001456 voice_media_info.receivers[0].packets_rcvd = 2;
1457 voice_media_info.receivers[0].bytes_rcvd = 3;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001458 voice_media_info.receivers[0].codec_payload_type = 42;
hboseeafe942016-11-01 03:00:17 -07001459 voice_media_info.receivers[0].jitter_ms = 4500;
1460 voice_media_info.receivers[0].fraction_lost = 5.5f;
hbos0adb8282016-11-23 02:32:06 -08001461
1462 RtpCodecParameters codec_parameters;
1463 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001464 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1465 codec_parameters.name = "dummy";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001466 codec_parameters.clock_rate = 0;
hbos0adb8282016-11-23 02:32:06 -08001467 voice_media_info.receive_codecs.insert(
1468 std::make_pair(codec_parameters.payload_type, codec_parameters));
1469
Steve Anton5b387312018-02-02 16:00:20 -08001470 auto* voice_media_channel = pc_->AddVoiceChannel("voice", kTransportName);
1471 voice_media_channel->SetStats(voice_media_info);
1472 stats_->SetupRemoteTrackAndReceiver(cricket::MEDIA_TYPE_AUDIO,
1473 "RemoteAudioTrackID", 1);
hboseeafe942016-11-01 03:00:17 -07001474
Steve Anton5b387312018-02-02 16:00:20 -08001475 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hboseeafe942016-11-01 03:00:17 -07001476
Harald Alvestranda3dab842018-01-14 09:18:58 +01001477 auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
1478 ASSERT_EQ(1, stats_of_track_type.size());
1479
hboseeafe942016-11-01 03:00:17 -07001480 RTCInboundRTPStreamStats expected_audio(
1481 "RTCInboundRTPAudioStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001482 expected_audio.ssrc = 1;
hboseeafe942016-11-01 03:00:17 -07001483 expected_audio.is_remote = false;
1484 expected_audio.media_type = "audio";
Harald Alvestranda3dab842018-01-14 09:18:58 +01001485 expected_audio.track_id = stats_of_track_type[0]->id();
Steve Anton5b387312018-02-02 16:00:20 -08001486 expected_audio.transport_id =
1487 "RTCTransport_TransportName_" +
hboseeafe942016-11-01 03:00:17 -07001488 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001489 expected_audio.codec_id = "RTCCodec_InboundAudio_42";
hboseeafe942016-11-01 03:00:17 -07001490 expected_audio.packets_received = 2;
1491 expected_audio.bytes_received = 3;
Harald Alvestrand719487e2017-12-13 12:26:04 +01001492 expected_audio.packets_lost = -1;
hboseeafe942016-11-01 03:00:17 -07001493 expected_audio.jitter = 4.5;
1494 expected_audio.fraction_lost = 5.5;
nissec8ee8822017-01-18 07:20:55 -08001495 ASSERT_TRUE(report->Get(expected_audio.id()));
hbosa51d4f32017-02-16 05:34:48 -08001496 EXPECT_EQ(
1497 report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
1498 expected_audio);
hbosb0ae9202017-01-27 06:35:16 -08001499 EXPECT_TRUE(report->Get(*expected_audio.track_id));
hbos84abeb12017-01-16 06:16:44 -08001500 EXPECT_TRUE(report->Get(*expected_audio.transport_id));
1501 EXPECT_TRUE(report->Get(*expected_audio.codec_id));
hboseeafe942016-11-01 03:00:17 -07001502}
1503
1504TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
hboseeafe942016-11-01 03:00:17 -07001505 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 02:32:06 -08001506
hboseeafe942016-11-01 03:00:17 -07001507 video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
1508 video_media_info.receivers[0].local_stats.push_back(
1509 cricket::SsrcReceiverInfo());
1510 video_media_info.receivers[0].local_stats[0].ssrc = 1;
1511 video_media_info.receivers[0].packets_rcvd = 2;
hbos02cd4d62016-12-09 04:19:44 -08001512 video_media_info.receivers[0].packets_lost = 42;
hboseeafe942016-11-01 03:00:17 -07001513 video_media_info.receivers[0].bytes_rcvd = 3;
1514 video_media_info.receivers[0].fraction_lost = 4.5f;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001515 video_media_info.receivers[0].codec_payload_type = 42;
hbos820f5782016-11-22 03:16:50 -08001516 video_media_info.receivers[0].firs_sent = 5;
1517 video_media_info.receivers[0].plis_sent = 6;
1518 video_media_info.receivers[0].nacks_sent = 7;
hbos6769c492017-01-02 08:35:13 -08001519 video_media_info.receivers[0].frames_decoded = 8;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001520 video_media_info.receivers[0].qp_sum = rtc::nullopt;
hbos0adb8282016-11-23 02:32:06 -08001521
1522 RtpCodecParameters codec_parameters;
1523 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001524 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1525 codec_parameters.name = "dummy";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001526 codec_parameters.clock_rate = 0;
hbos0adb8282016-11-23 02:32:06 -08001527 video_media_info.receive_codecs.insert(
1528 std::make_pair(codec_parameters.payload_type, codec_parameters));
1529
Steve Anton5b387312018-02-02 16:00:20 -08001530 auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
1531 video_media_channel->SetStats(video_media_info);
1532 stats_->SetupRemoteTrackAndReceiver(cricket::MEDIA_TYPE_VIDEO,
1533 "RemoteVideoTrackID", 1);
hboseeafe942016-11-01 03:00:17 -07001534
Steve Anton5b387312018-02-02 16:00:20 -08001535 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hboseeafe942016-11-01 03:00:17 -07001536
hbos820f5782016-11-22 03:16:50 -08001537 RTCInboundRTPStreamStats expected_video(
hboseeafe942016-11-01 03:00:17 -07001538 "RTCInboundRTPVideoStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001539 expected_video.ssrc = 1;
hbos820f5782016-11-22 03:16:50 -08001540 expected_video.is_remote = false;
1541 expected_video.media_type = "video";
Harald Alvestranda3dab842018-01-14 09:18:58 +01001542 expected_video.track_id = IdForType<RTCMediaStreamTrackStats>(report);
hbos820f5782016-11-22 03:16:50 -08001543 expected_video.transport_id = "RTCTransport_TransportName_" +
hboseeafe942016-11-01 03:00:17 -07001544 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001545 expected_video.codec_id = "RTCCodec_InboundVideo_42";
hbos820f5782016-11-22 03:16:50 -08001546 expected_video.fir_count = 5;
1547 expected_video.pli_count = 6;
1548 expected_video.nack_count = 7;
1549 expected_video.packets_received = 2;
1550 expected_video.bytes_received = 3;
hbos02cd4d62016-12-09 04:19:44 -08001551 expected_video.packets_lost = 42;
hbos820f5782016-11-22 03:16:50 -08001552 expected_video.fraction_lost = 4.5;
hbos6769c492017-01-02 08:35:13 -08001553 expected_video.frames_decoded = 8;
hbosa51d4f32017-02-16 05:34:48 -08001554 // |expected_video.qp_sum| should be undefined.
hboseeafe942016-11-01 03:00:17 -07001555
nissec8ee8822017-01-18 07:20:55 -08001556 ASSERT_TRUE(report->Get(expected_video.id()));
hbosa51d4f32017-02-16 05:34:48 -08001557 EXPECT_EQ(
1558 report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
1559 expected_video);
hboseeafe942016-11-01 03:00:17 -07001560
hbosa51d4f32017-02-16 05:34:48 -08001561 // Set previously undefined values and "GetStats" again.
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001562 video_media_info.receivers[0].qp_sum = 9;
hbosa51d4f32017-02-16 05:34:48 -08001563 expected_video.qp_sum = 9;
Steve Anton5b387312018-02-02 16:00:20 -08001564 video_media_channel->SetStats(video_media_info);
hbosa51d4f32017-02-16 05:34:48 -08001565
Steve Anton5b387312018-02-02 16:00:20 -08001566 report = stats_->GetFreshStatsReport();
hbosa51d4f32017-02-16 05:34:48 -08001567
1568 ASSERT_TRUE(report->Get(expected_video.id()));
1569 EXPECT_EQ(
1570 report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
1571 expected_video);
hbosb0ae9202017-01-27 06:35:16 -08001572 EXPECT_TRUE(report->Get(*expected_video.track_id));
hbos84abeb12017-01-16 06:16:44 -08001573 EXPECT_TRUE(report->Get(*expected_video.transport_id));
hbosa51d4f32017-02-16 05:34:48 -08001574 EXPECT_TRUE(report->Get(*expected_video.codec_id));
hboseeafe942016-11-01 03:00:17 -07001575}
1576
hbos6ded1902016-11-01 01:50:46 -07001577TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
hbos6ded1902016-11-01 01:50:46 -07001578 cricket::VoiceMediaInfo voice_media_info;
hbos0adb8282016-11-23 02:32:06 -08001579
hbos6ded1902016-11-01 01:50:46 -07001580 voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
1581 voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1582 voice_media_info.senders[0].local_stats[0].ssrc = 1;
1583 voice_media_info.senders[0].packets_sent = 2;
1584 voice_media_info.senders[0].bytes_sent = 3;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001585 voice_media_info.senders[0].codec_payload_type = 42;
hbos0adb8282016-11-23 02:32:06 -08001586
1587 RtpCodecParameters codec_parameters;
1588 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001589 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1590 codec_parameters.name = "dummy";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001591 codec_parameters.clock_rate = 0;
hbos0adb8282016-11-23 02:32:06 -08001592 voice_media_info.send_codecs.insert(
1593 std::make_pair(codec_parameters.payload_type, codec_parameters));
1594
Steve Anton5b387312018-02-02 16:00:20 -08001595 auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
1596 voice_media_channel->SetStats(voice_media_info);
1597 stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
1598 "LocalAudioTrackID", 1, true);
hbos6ded1902016-11-01 01:50:46 -07001599
Steve Anton5b387312018-02-02 16:00:20 -08001600 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos6ded1902016-11-01 01:50:46 -07001601
1602 RTCOutboundRTPStreamStats expected_audio(
1603 "RTCOutboundRTPAudioStream_1", report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001604 expected_audio.ssrc = 1;
hbos6ded1902016-11-01 01:50:46 -07001605 expected_audio.is_remote = false;
1606 expected_audio.media_type = "audio";
Harald Alvestranda3dab842018-01-14 09:18:58 +01001607 expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
hbos6ded1902016-11-01 01:50:46 -07001608 expected_audio.transport_id = "RTCTransport_TransportName_" +
1609 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001610 expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
hbos6ded1902016-11-01 01:50:46 -07001611 expected_audio.packets_sent = 2;
1612 expected_audio.bytes_sent = 3;
hboscd195be2017-02-07 08:31:27 -08001613
hboscd195be2017-02-07 08:31:27 -08001614 ASSERT_TRUE(report->Get(expected_audio.id()));
hbosa51d4f32017-02-16 05:34:48 -08001615 EXPECT_EQ(
1616 report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
1617 expected_audio);
skvladed02c6d2017-02-07 10:45:31 -08001618
hbosa51d4f32017-02-16 05:34:48 -08001619 ASSERT_TRUE(report->Get(expected_audio.id()));
1620 EXPECT_EQ(
1621 report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
1622 expected_audio);
hbosb0ae9202017-01-27 06:35:16 -08001623 EXPECT_TRUE(report->Get(*expected_audio.track_id));
hbos84abeb12017-01-16 06:16:44 -08001624 EXPECT_TRUE(report->Get(*expected_audio.transport_id));
1625 EXPECT_TRUE(report->Get(*expected_audio.codec_id));
hbos6ded1902016-11-01 01:50:46 -07001626}
1627
1628TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
hbos6ded1902016-11-01 01:50:46 -07001629 cricket::VideoMediaInfo video_media_info;
hbos0adb8282016-11-23 02:32:06 -08001630
hbos6ded1902016-11-01 01:50:46 -07001631 video_media_info.senders.push_back(cricket::VideoSenderInfo());
1632 video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1633 video_media_info.senders[0].local_stats[0].ssrc = 1;
1634 video_media_info.senders[0].firs_rcvd = 2;
1635 video_media_info.senders[0].plis_rcvd = 3;
1636 video_media_info.senders[0].nacks_rcvd = 4;
1637 video_media_info.senders[0].packets_sent = 5;
1638 video_media_info.senders[0].bytes_sent = 6;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001639 video_media_info.senders[0].codec_payload_type = 42;
hbos6769c492017-01-02 08:35:13 -08001640 video_media_info.senders[0].frames_encoded = 8;
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001641 video_media_info.senders[0].qp_sum = rtc::nullopt;
hbos0adb8282016-11-23 02:32:06 -08001642
1643 RtpCodecParameters codec_parameters;
1644 codec_parameters.payload_type = 42;
deadbeefe702b302017-02-04 12:09:01 -08001645 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1646 codec_parameters.name = "dummy";
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001647 codec_parameters.clock_rate = 0;
hbos0adb8282016-11-23 02:32:06 -08001648 video_media_info.send_codecs.insert(
1649 std::make_pair(codec_parameters.payload_type, codec_parameters));
1650
Steve Anton5b387312018-02-02 16:00:20 -08001651 auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
1652 video_media_channel->SetStats(video_media_info);
1653 stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_VIDEO,
1654 "LocalVideoTrackID", 1, true);
hbos6ded1902016-11-01 01:50:46 -07001655
Steve Anton5b387312018-02-02 16:00:20 -08001656 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos6ded1902016-11-01 01:50:46 -07001657
Harald Alvestranda3dab842018-01-14 09:18:58 +01001658 auto stats_of_my_type = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
1659 ASSERT_EQ(1, stats_of_my_type.size());
1660 auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
1661 ASSERT_EQ(1, stats_of_track_type.size());
1662
1663 RTCOutboundRTPStreamStats expected_video(stats_of_my_type[0]->id(),
1664 report->timestamp_us());
hbos3443bb72017-02-07 06:28:11 -08001665 expected_video.ssrc = 1;
hbos6ded1902016-11-01 01:50:46 -07001666 expected_video.is_remote = false;
1667 expected_video.media_type = "video";
Harald Alvestranda3dab842018-01-14 09:18:58 +01001668 expected_video.track_id = stats_of_track_type[0]->id();
hbos6ded1902016-11-01 01:50:46 -07001669 expected_video.transport_id = "RTCTransport_TransportName_" +
1670 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
hbos0adb8282016-11-23 02:32:06 -08001671 expected_video.codec_id = "RTCCodec_OutboundVideo_42";
hbos6ded1902016-11-01 01:50:46 -07001672 expected_video.fir_count = 2;
1673 expected_video.pli_count = 3;
1674 expected_video.nack_count = 4;
1675 expected_video.packets_sent = 5;
1676 expected_video.bytes_sent = 6;
skvladed02c6d2017-02-07 10:45:31 -08001677 expected_video.frames_encoded = 8;
hbosa7a9be12017-03-01 01:02:45 -08001678 // |expected_video.qp_sum| should be undefined.
hboscd195be2017-02-07 08:31:27 -08001679 ASSERT_TRUE(report->Get(expected_video.id()));
Harald Alvestranda3dab842018-01-14 09:18:58 +01001680
hbosa51d4f32017-02-16 05:34:48 -08001681 EXPECT_EQ(
1682 report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
1683 expected_video);
skvladed02c6d2017-02-07 10:45:31 -08001684
hbosa51d4f32017-02-16 05:34:48 -08001685 // Set previously undefined values and "GetStats" again.
Oskar Sundbomcbc71b22017-11-16 10:56:07 +01001686 video_media_info.senders[0].qp_sum = 9;
hbosa51d4f32017-02-16 05:34:48 -08001687 expected_video.qp_sum = 9;
Steve Anton5b387312018-02-02 16:00:20 -08001688 video_media_channel->SetStats(video_media_info);
hbosa51d4f32017-02-16 05:34:48 -08001689
Steve Anton5b387312018-02-02 16:00:20 -08001690 report = stats_->GetFreshStatsReport();
hbosa51d4f32017-02-16 05:34:48 -08001691
1692 ASSERT_TRUE(report->Get(expected_video.id()));
1693 EXPECT_EQ(
1694 report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
1695 expected_video);
hbosb0ae9202017-01-27 06:35:16 -08001696 EXPECT_TRUE(report->Get(*expected_video.track_id));
hbos84abeb12017-01-16 06:16:44 -08001697 EXPECT_TRUE(report->Get(*expected_video.transport_id));
1698 EXPECT_TRUE(report->Get(*expected_video.codec_id));
hbos6ded1902016-11-01 01:50:46 -07001699}
1700
hbos2fa7c672016-10-24 04:00:05 -07001701TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
Steve Anton5b387312018-02-02 16:00:20 -08001702 const char kTransportName[] = "transport";
1703
1704 pc_->AddVoiceChannel("audio", kTransportName);
1705
Gary Liu37e489c2017-11-21 10:49:36 -08001706 std::unique_ptr<cricket::Candidate> rtp_local_candidate =
1707 CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
1708 cricket::LOCAL_PORT_TYPE, 42);
hbos2fa7c672016-10-24 04:00:05 -07001709 std::unique_ptr<cricket::Candidate> rtp_remote_candidate =
1710 CreateFakeCandidate("42.42.42.42", 42, "protocol",
Gary Liu37e489c2017-11-21 10:49:36 -08001711 rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
1712 42);
hbos2fa7c672016-10-24 04:00:05 -07001713 std::unique_ptr<cricket::Candidate> rtcp_local_candidate =
Gary Liu37e489c2017-11-21 10:49:36 -08001714 CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
hbos2fa7c672016-10-24 04:00:05 -07001715 cricket::LOCAL_PORT_TYPE, 42);
1716 std::unique_ptr<cricket::Candidate> rtcp_remote_candidate =
1717 CreateFakeCandidate("42.42.42.42", 42, "protocol",
Gary Liu37e489c2017-11-21 10:49:36 -08001718 rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
1719 42);
hbos2fa7c672016-10-24 04:00:05 -07001720
hbos2fa7c672016-10-24 04:00:05 -07001721 cricket::ConnectionInfo rtp_connection_info;
1722 rtp_connection_info.best_connection = false;
1723 rtp_connection_info.local_candidate = *rtp_local_candidate.get();
1724 rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
1725 rtp_connection_info.sent_total_bytes = 42;
1726 rtp_connection_info.recv_total_bytes = 1337;
1727 cricket::TransportChannelStats rtp_transport_channel_stats;
1728 rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
1729 rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info);
hbos7064d592017-01-16 07:38:02 -08001730 rtp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_NEW;
Steve Anton5b387312018-02-02 16:00:20 -08001731 pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
hbos2fa7c672016-10-24 04:00:05 -07001732
1733 // Get stats without RTCP, an active connection or certificates.
Steve Anton5b387312018-02-02 16:00:20 -08001734 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
hbos0583b282016-11-30 01:50:14 -08001735
1736 RTCTransportStats expected_rtp_transport(
1737 "RTCTransport_transport_" +
1738 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP),
1739 report->timestamp_us());
1740 expected_rtp_transport.bytes_sent = 42;
1741 expected_rtp_transport.bytes_received = 1337;
hbos7064d592017-01-16 07:38:02 -08001742 expected_rtp_transport.dtls_state = RTCDtlsTransportState::kNew;
hbos0583b282016-11-30 01:50:14 -08001743
hbosdbb64d82016-12-21 01:57:46 -08001744 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001745 EXPECT_EQ(
1746 expected_rtp_transport,
1747 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07001748
1749 cricket::ConnectionInfo rtcp_connection_info;
1750 rtcp_connection_info.best_connection = false;
1751 rtcp_connection_info.local_candidate = *rtcp_local_candidate.get();
1752 rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get();
1753 rtcp_connection_info.sent_total_bytes = 1337;
1754 rtcp_connection_info.recv_total_bytes = 42;
1755 cricket::TransportChannelStats rtcp_transport_channel_stats;
1756 rtcp_transport_channel_stats.component =
1757 cricket::ICE_CANDIDATE_COMPONENT_RTCP;
1758 rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info);
hbos7064d592017-01-16 07:38:02 -08001759 rtcp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_CONNECTING;
Steve Anton5b387312018-02-02 16:00:20 -08001760 pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
1761 rtcp_transport_channel_stats});
hbos2fa7c672016-10-24 04:00:05 -07001762
hbos2fa7c672016-10-24 04:00:05 -07001763 // Get stats with RTCP and without an active connection or certificates.
Steve Anton5b387312018-02-02 16:00:20 -08001764 report = stats_->GetFreshStatsReport();
hbos0583b282016-11-30 01:50:14 -08001765
1766 RTCTransportStats expected_rtcp_transport(
1767 "RTCTransport_transport_" +
1768 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTCP),
1769 report->timestamp_us());
1770 expected_rtcp_transport.bytes_sent = 1337;
1771 expected_rtcp_transport.bytes_received = 42;
hbos7064d592017-01-16 07:38:02 -08001772 expected_rtcp_transport.dtls_state = RTCDtlsTransportState::kConnecting;
hbos0583b282016-11-30 01:50:14 -08001773
1774 expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
1775
hbosdbb64d82016-12-21 01:57:46 -08001776 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001777 EXPECT_EQ(
1778 expected_rtp_transport,
1779 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08001780 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001781 EXPECT_EQ(
1782 expected_rtcp_transport,
1783 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07001784
hbos7064d592017-01-16 07:38:02 -08001785 // Get stats with an active connection (selected candidate pair).
Steve Anton5b387312018-02-02 16:00:20 -08001786 rtcp_transport_channel_stats.connection_infos[0].best_connection = true;
1787 pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
1788 rtcp_transport_channel_stats});
hbos2fa7c672016-10-24 04:00:05 -07001789
Steve Anton5b387312018-02-02 16:00:20 -08001790 report = stats_->GetFreshStatsReport();
hbos0583b282016-11-30 01:50:14 -08001791
hbos0583b282016-11-30 01:50:14 -08001792 expected_rtcp_transport.selected_candidate_pair_id =
1793 "RTCIceCandidatePair_" + rtcp_local_candidate->id() + "_" +
1794 rtcp_remote_candidate->id();
1795
hbosdbb64d82016-12-21 01:57:46 -08001796 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001797 EXPECT_EQ(
1798 expected_rtp_transport,
1799 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08001800 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001801 EXPECT_EQ(
1802 expected_rtcp_transport,
1803 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07001804
1805 // Get stats with certificates.
1806 std::unique_ptr<CertificateInfo> local_certinfo =
Steve Anton5b387312018-02-02 16:00:20 -08001807 CreateFakeCertificateAndInfoFromDers({"(local) local", "(local) chain"});
1808 pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
hbos2fa7c672016-10-24 04:00:05 -07001809 std::unique_ptr<CertificateInfo> remote_certinfo =
1810 CreateFakeCertificateAndInfoFromDers(
Steve Anton5b387312018-02-02 16:00:20 -08001811 {"(remote) local", "(remote) chain"});
1812 pc_->SetRemoteCertificate(
1813 kTransportName,
1814 remote_certinfo->certificate->ssl_certificate().GetUniqueReference());
hbos2fa7c672016-10-24 04:00:05 -07001815
Steve Anton5b387312018-02-02 16:00:20 -08001816 report = stats_->GetFreshStatsReport();
hbos0583b282016-11-30 01:50:14 -08001817
1818 expected_rtp_transport.local_certificate_id =
1819 "RTCCertificate_" + local_certinfo->fingerprints[0];
1820 expected_rtp_transport.remote_certificate_id =
1821 "RTCCertificate_" + remote_certinfo->fingerprints[0];
1822
1823 expected_rtcp_transport.local_certificate_id =
1824 *expected_rtp_transport.local_certificate_id;
1825 expected_rtcp_transport.remote_certificate_id =
1826 *expected_rtp_transport.remote_certificate_id;
1827
hbosdbb64d82016-12-21 01:57:46 -08001828 ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001829 EXPECT_EQ(
1830 expected_rtp_transport,
1831 report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
hbosdbb64d82016-12-21 01:57:46 -08001832 ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
hbos0583b282016-11-30 01:50:14 -08001833 EXPECT_EQ(
1834 expected_rtcp_transport,
1835 report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
hbos2fa7c672016-10-24 04:00:05 -07001836}
1837
Harald Alvestrand89061872018-01-02 14:08:34 +01001838TEST_F(RTCStatsCollectorTest, CollectNoStreamRTCOutboundRTPStreamStats_Audio) {
Harald Alvestrand89061872018-01-02 14:08:34 +01001839 cricket::VoiceMediaInfo voice_media_info;
1840
1841 voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
1842 voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
1843 voice_media_info.senders[0].local_stats[0].ssrc = 1;
1844 voice_media_info.senders[0].packets_sent = 2;
1845 voice_media_info.senders[0].bytes_sent = 3;
1846 voice_media_info.senders[0].codec_payload_type = 42;
1847
1848 RtpCodecParameters codec_parameters;
1849 codec_parameters.payload_type = 42;
1850 codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
1851 codec_parameters.name = "dummy";
1852 codec_parameters.clock_rate = 0;
1853 voice_media_info.send_codecs.insert(
1854 std::make_pair(codec_parameters.payload_type, codec_parameters));
1855
Steve Anton5b387312018-02-02 16:00:20 -08001856 // Emulates the case where AddTrack is used without an associated MediaStream
1857 auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
1858 voice_media_channel->SetStats(voice_media_info);
1859 stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
1860 "LocalAudioTrackID", 1, false);
Harald Alvestrand89061872018-01-02 14:08:34 +01001861
Steve Anton5b387312018-02-02 16:00:20 -08001862 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
Harald Alvestrand89061872018-01-02 14:08:34 +01001863
1864 RTCOutboundRTPStreamStats expected_audio("RTCOutboundRTPAudioStream_1",
1865 report->timestamp_us());
1866 expected_audio.ssrc = 1;
1867 expected_audio.is_remote = false;
1868 expected_audio.media_type = "audio";
Harald Alvestranda3dab842018-01-14 09:18:58 +01001869 expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
Harald Alvestrand89061872018-01-02 14:08:34 +01001870 expected_audio.transport_id =
1871 "RTCTransport_TransportName_" +
1872 rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
1873 expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
1874 expected_audio.packets_sent = 2;
1875 expected_audio.bytes_sent = 3;
1876
1877 ASSERT_TRUE(report->Get(expected_audio.id()));
1878 EXPECT_EQ(
1879 report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
1880 expected_audio);
Harald Alvestrand89061872018-01-02 14:08:34 +01001881 EXPECT_TRUE(report->Get(*expected_audio.track_id));
1882 EXPECT_TRUE(report->Get(*expected_audio.transport_id));
1883 EXPECT_TRUE(report->Get(*expected_audio.codec_id));
1884}
1885
1886// When the PC has not had SetLocalDescription done, tracks all have
1887// SSRC 0, meaning "unconnected".
Harald Alvestrandb8e12012018-01-23 15:28:16 +01001888// In this state, we report on track stats, but not RTP stats.
1889TEST_F(RTCStatsCollectorTest, StatsReportedOnZeroSsrc) {
Harald Alvestrand89061872018-01-02 14:08:34 +01001890 rtc::scoped_refptr<MediaStreamTrackInterface> track =
1891 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
1892 MediaStreamTrackInterface::kLive);
Harald Alvestranda3dab842018-01-14 09:18:58 +01001893 rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, 0, 49, {});
Steve Anton5b387312018-02-02 16:00:20 -08001894 pc_->AddSender(sender);
1895
1896 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
1897
Harald Alvestrand89061872018-01-02 14:08:34 +01001898 std::vector<const RTCMediaStreamTrackStats*> track_stats =
1899 report->GetStatsOfType<RTCMediaStreamTrackStats>();
Harald Alvestrandb8e12012018-01-23 15:28:16 +01001900 EXPECT_EQ(1, track_stats.size());
Steve Anton5b387312018-02-02 16:00:20 -08001901
Harald Alvestrandb8e12012018-01-23 15:28:16 +01001902 std::vector<const RTCRTPStreamStats*> rtp_stream_stats =
1903 report->GetStatsOfType<RTCRTPStreamStats>();
1904 EXPECT_EQ(0, rtp_stream_stats.size());
Harald Alvestrand89061872018-01-02 14:08:34 +01001905}
1906
Harald Alvestrand76d29522018-01-30 14:43:29 +01001907TEST_F(RTCStatsCollectorTest, DoNotCrashOnSsrcChange) {
1908 rtc::scoped_refptr<MediaStreamTrackInterface> track =
1909 CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
1910 MediaStreamTrackInterface::kLive);
1911 rtc::scoped_refptr<MockRtpSender> sender =
1912 CreateMockSender(track, 4711, 49, {});
Steve Anton5b387312018-02-02 16:00:20 -08001913 pc_->AddSender(sender);
1914
Harald Alvestrand76d29522018-01-30 14:43:29 +01001915 // We do not generate any matching voice_sender_info stats.
Steve Anton5b387312018-02-02 16:00:20 -08001916 rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
1917
Harald Alvestrand76d29522018-01-30 14:43:29 +01001918 std::vector<const RTCMediaStreamTrackStats*> track_stats =
1919 report->GetStatsOfType<RTCMediaStreamTrackStats>();
1920 EXPECT_EQ(1, track_stats.size());
1921}
1922
Steve Anton5b387312018-02-02 16:00:20 -08001923class RTCTestStats : public RTCStats {
hbosc82f2e12016-09-05 01:36:50 -07001924 public:
Steve Anton5b387312018-02-02 16:00:20 -08001925 WEBRTC_RTCSTATS_DECL();
1926
1927 RTCTestStats(const std::string& id, int64_t timestamp_us)
1928 : RTCStats(id, timestamp_us), dummy_stat("dummyStat") {}
1929
1930 RTCStatsMember<int32_t> dummy_stat;
1931};
1932
1933WEBRTC_RTCSTATS_IMPL(RTCTestStats, RTCStats, "test-stats", &dummy_stat);
1934
1935// Overrides the stats collection to verify thread usage and that the resulting
1936// partial reports are merged.
1937class FakeRTCStatsCollector : public RTCStatsCollector,
1938 public RTCStatsCollectorCallback {
1939 public:
1940 static rtc::scoped_refptr<FakeRTCStatsCollector> Create(
1941 PeerConnectionInternal* pc,
1942 int64_t cache_lifetime_us) {
1943 return rtc::scoped_refptr<FakeRTCStatsCollector>(
1944 new rtc::RefCountedObject<FakeRTCStatsCollector>(pc,
1945 cache_lifetime_us));
1946 }
1947
1948 // RTCStatsCollectorCallback implementation.
1949 void OnStatsDelivered(
1950 const rtc::scoped_refptr<const RTCStatsReport>& report) override {
1951 EXPECT_TRUE(signaling_thread_->IsCurrent());
1952 rtc::CritScope cs(&lock_);
1953 delivered_report_ = report;
1954 }
1955
1956 void VerifyThreadUsageAndResultsMerging() {
1957 GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback>(this));
1958 EXPECT_TRUE_WAIT(HasVerifiedResults(), kGetStatsReportTimeoutMs);
1959 }
1960
1961 bool HasVerifiedResults() {
1962 EXPECT_TRUE(signaling_thread_->IsCurrent());
1963 rtc::CritScope cs(&lock_);
1964 if (!delivered_report_)
1965 return false;
1966 EXPECT_EQ(produced_on_signaling_thread_, 1);
1967 EXPECT_EQ(produced_on_network_thread_, 1);
1968
1969 EXPECT_TRUE(delivered_report_->Get("SignalingThreadStats"));
1970 EXPECT_TRUE(delivered_report_->Get("NetworkThreadStats"));
1971
1972 produced_on_signaling_thread_ = 0;
1973 produced_on_network_thread_ = 0;
1974 delivered_report_ = nullptr;
1975 return true;
hbosc82f2e12016-09-05 01:36:50 -07001976 }
1977
1978 protected:
Steve Anton5b387312018-02-02 16:00:20 -08001979 FakeRTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime)
1980 : RTCStatsCollector(pc, cache_lifetime),
1981 signaling_thread_(pc->signaling_thread()),
1982 worker_thread_(pc->worker_thread()),
1983 network_thread_(pc->network_thread()) {}
1984
1985 void ProducePartialResultsOnSignalingThread(int64_t timestamp_us) override {
1986 EXPECT_TRUE(signaling_thread_->IsCurrent());
1987 {
1988 rtc::CritScope cs(&lock_);
1989 EXPECT_FALSE(delivered_report_);
1990 ++produced_on_signaling_thread_;
1991 }
1992
1993 rtc::scoped_refptr<RTCStatsReport> signaling_report =
1994 RTCStatsReport::Create(0);
1995 signaling_report->AddStats(std::unique_ptr<const RTCStats>(
1996 new RTCTestStats("SignalingThreadStats", timestamp_us)));
1997 AddPartialResults(signaling_report);
1998 }
1999 void ProducePartialResultsOnNetworkThread(int64_t timestamp_us) override {
2000 EXPECT_TRUE(network_thread_->IsCurrent());
2001 {
2002 rtc::CritScope cs(&lock_);
2003 EXPECT_FALSE(delivered_report_);
2004 ++produced_on_network_thread_;
2005 }
2006
2007 rtc::scoped_refptr<RTCStatsReport> network_report =
2008 RTCStatsReport::Create(0);
2009 network_report->AddStats(std::unique_ptr<const RTCStats>(
2010 new RTCTestStats("NetworkThreadStats", timestamp_us)));
2011 AddPartialResults(network_report);
2012 }
2013
2014 private:
2015 rtc::Thread* const signaling_thread_;
2016 rtc::Thread* const worker_thread_;
2017 rtc::Thread* const network_thread_;
2018
2019 rtc::CriticalSection lock_;
2020 rtc::scoped_refptr<const RTCStatsReport> delivered_report_;
2021 int produced_on_signaling_thread_ = 0;
2022 int produced_on_network_thread_ = 0;
hbosc82f2e12016-09-05 01:36:50 -07002023};
2024
Steve Anton5b387312018-02-02 16:00:20 -08002025TEST(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) {
2026 rtc::scoped_refptr<FakePeerConnectionForStats> pc(
2027 new rtc::RefCountedObject<FakePeerConnectionForStats>());
2028 rtc::scoped_refptr<FakeRTCStatsCollector> stats_collector(
2029 FakeRTCStatsCollector::Create(pc, 50 * rtc::kNumMicrosecsPerMillisec));
2030 stats_collector->VerifyThreadUsageAndResultsMerging();
hbosc82f2e12016-09-05 01:36:50 -07002031}
2032
2033} // namespace
2034
hbosd565b732016-08-30 14:04:35 -07002035} // namespace webrtc