blob: cba4003906032d23eeaf18f21a55405f9e4b7698 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
xians@webrtc.org4cb01282014-06-12 14:57:05 +00003 * Copyright 2014, Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <stdio.h>
29
30#include "talk/app/webrtc/statscollector.h"
31
32#include "talk/app/webrtc/mediastream.h"
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000033#include "talk/app/webrtc/mediastreaminterface.h"
decurtis@webrtc.org487a4442015-01-15 22:55:07 +000034#include "talk/app/webrtc/mediastreamsignaling.h"
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000035#include "talk/app/webrtc/mediastreamtrack.h"
decurtis@webrtc.org487a4442015-01-15 22:55:07 +000036#include "talk/app/webrtc/test/fakedatachannelprovider.h"
37#include "talk/app/webrtc/test/fakemediastreamsignaling.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/app/webrtc/videotrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/media/base/fakemediaengine.h"
40#include "talk/media/devices/fakedevicemanager.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041#include "talk/session/media/channelmanager.h"
xians@webrtc.org4cb01282014-06-12 14:57:05 +000042#include "testing/gmock/include/gmock/gmock.h"
43#include "testing/gtest/include/gtest/gtest.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000044#include "webrtc/base/base64.h"
45#include "webrtc/base/fakesslidentity.h"
46#include "webrtc/base/gunit.h"
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000047#include "webrtc/base/network.h"
decurtis@webrtc.org487a4442015-01-15 22:55:07 +000048#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000050using cricket::StatsOptions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051using testing::_;
52using testing::DoAll;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000053using testing::Field;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054using testing::Return;
55using testing::ReturnNull;
56using testing::SetArgPointee;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000057using webrtc::PeerConnectionInterface;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000058using webrtc::StatsReport;
59using webrtc::StatsReports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
61namespace cricket {
62
63class ChannelManager;
64class FakeDeviceManager;
65
66} // namespace cricket
67
guoweis@webrtc.org950c5182014-12-16 23:01:31 +000068namespace webrtc {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
70// Error return values
71const char kNotFound[] = "NOT FOUND";
72const char kNoReports[] = "NO REPORTS";
73
wu@webrtc.org97077a32013-10-25 21:18:33 +000074// Constant names for track identification.
xians@webrtc.org4cb01282014-06-12 14:57:05 +000075const char kLocalTrackId[] = "local_track_id";
76const char kRemoteTrackId[] = "remote_track_id";
wu@webrtc.org97077a32013-10-25 21:18:33 +000077const uint32 kSsrcOfTrack = 1234;
78
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079class MockWebRtcSession : public webrtc::WebRtcSession {
80 public:
81 explicit MockWebRtcSession(cricket::ChannelManager* channel_manager)
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000082 : WebRtcSession(channel_manager, rtc::Thread::Current(),
83 rtc::Thread::Current(), NULL, NULL) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000085 MOCK_METHOD0(voice_channel, cricket::VoiceChannel*());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 MOCK_METHOD0(video_channel, cricket::VideoChannel*());
decurtis@webrtc.org487a4442015-01-15 22:55:07 +000087 MOCK_CONST_METHOD0(mediastream_signaling, const MediaStreamSignaling*());
xians@webrtc.org4cb01282014-06-12 14:57:05 +000088 // Libjingle uses "local" for a outgoing track, and "remote" for a incoming
89 // track.
90 MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32, std::string*));
91 MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32, std::string*));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092 MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
wu@webrtc.org4551b792013-10-09 15:37:36 +000093 MOCK_METHOD1(GetTransport, cricket::Transport*(const std::string&));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094};
95
96class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
97 public:
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +000098 MockVideoMediaChannel() : cricket::FakeVideoMediaChannel(NULL) {}
99
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100 // MOCK_METHOD0(transport_channel, cricket::TransportChannel*());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000101 MOCK_METHOD2(GetStats, bool(const StatsOptions&, cricket::VideoMediaInfo*));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102};
103
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000104class MockVoiceMediaChannel : public cricket::FakeVoiceMediaChannel {
105 public:
106 MockVoiceMediaChannel() : cricket::FakeVoiceMediaChannel(NULL) {
107 }
108 MOCK_METHOD1(GetStats, bool(cricket::VoiceMediaInfo*));
109};
110
111class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
112 public:
113 FakeAudioProcessor() {}
114 ~FakeAudioProcessor() {}
115
116 private:
117 virtual void GetStats(
118 AudioProcessorInterface::AudioProcessorStats* stats) OVERRIDE {
119 stats->typing_noise_detected = true;
120 stats->echo_return_loss = 2;
121 stats->echo_return_loss_enhancement = 3;
122 stats->echo_delay_median_ms = 4;
123 stats->aec_quality_min = 5.1f;
124 stats->echo_delay_std_ms = 6;
125 }
126};
127
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000128class FakeAudioTrack
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000129 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
130 public:
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000131 explicit FakeAudioTrack(const std::string& id)
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000132 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000133 processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000134 std::string kind() const OVERRIDE {
135 return "audio";
136 }
137 virtual webrtc::AudioSourceInterface* GetSource() const OVERRIDE {
138 return NULL;
139 }
140 virtual void AddSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
141 virtual void RemoveSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
142 virtual bool GetSignalLevel(int* level) OVERRIDE {
143 *level = 1;
144 return true;
145 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000146 virtual rtc::scoped_refptr<webrtc::AudioProcessorInterface>
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000147 GetAudioProcessor() OVERRIDE {
148 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000149 }
150
151 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000152 rtc::scoped_refptr<FakeAudioProcessor> processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000153};
154
155bool GetValue(const StatsReport* report,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000156 StatsReport::StatsValueName name,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000157 std::string* value) {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000158 StatsReport::Values::const_iterator it = report->values.begin();
wu@webrtc.org4551b792013-10-09 15:37:36 +0000159 for (; it != report->values.end(); ++it) {
160 if (it->name == name) {
161 *value = it->value;
162 return true;
163 }
164 }
165 return false;
166}
167
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168std::string ExtractStatsValue(const std::string& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000169 const StatsReports& reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000170 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 if (reports.empty()) {
172 return kNoReports;
173 }
174 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000175 if (reports[i]->type != type)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 continue;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000177 std::string ret;
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000178 if (GetValue(reports[i], name, &ret)) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000179 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 }
181 }
182
183 return kNotFound;
184}
185
186// Finds the |n|-th report of type |type| in |reports|.
187// |n| starts from 1 for finding the first report.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000188const StatsReport* FindNthReportByType(
189 const StatsReports& reports, const std::string& type, int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000191 if (reports[i]->type == type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192 n--;
193 if (n == 0)
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000194 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195 }
196 }
197 return NULL;
198}
199
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000200const StatsReport* FindReportById(const StatsReports& reports,
201 const std::string& id) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 for (size_t i = 0; i < reports.size(); ++i) {
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000203 if (reports[i]->id == id) {
204 return reports[i];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
206 }
207 return NULL;
208}
209
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000210std::string ExtractSsrcStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000211 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000213 StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214}
215
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000216std::string ExtractBweStatsValue(StatsReports reports,
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000217 StatsReport::StatsValueName name) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000219 StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220}
221
wu@webrtc.org4551b792013-10-09 15:37:36 +0000222std::string DerToPem(const std::string& der) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000223 return rtc::SSLIdentity::DerToPem(
224 rtc::kPemTypeCertificate,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000225 reinterpret_cast<const unsigned char*>(der.c_str()),
226 der.length());
227}
228
229std::vector<std::string> DersToPems(
230 const std::vector<std::string>& ders) {
231 std::vector<std::string> pems(ders.size());
232 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
233 return pems;
234}
235
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000236void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000237 const std::vector<std::string>& ders,
238 const std::string& start_id) {
239 std::string certificate_id = start_id;
240 size_t i = 0;
241 while (true) {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000242 const StatsReport* report = FindReportById(reports, certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000243 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000244
wu@webrtc.org4551b792013-10-09 15:37:36 +0000245 std::string der_base64;
246 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000247 report, StatsReport::kStatsValueNameDer, &der_base64));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000248 std::string der = rtc::Base64::Decode(der_base64,
249 rtc::Base64::DO_STRICT);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000250 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000251
252 std::string fingerprint_algorithm;
253 EXPECT_TRUE(GetValue(
254 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000255 StatsReport::kStatsValueNameFingerprintAlgorithm,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000256 &fingerprint_algorithm));
257 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000258 std::string sha_1_str = rtc::DIGEST_SHA_1;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000259 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
260
261 std::string dummy_fingerprint; // Value is not checked.
262 EXPECT_TRUE(GetValue(
263 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000264 StatsReport::kStatsValueNameFingerprint,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000265 &dummy_fingerprint));
266
wu@webrtc.org4551b792013-10-09 15:37:36 +0000267 ++i;
268 if (!GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000269 report, StatsReport::kStatsValueNameIssuerId, &certificate_id))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000270 break;
271 }
272 EXPECT_EQ(ders.size(), i);
273}
274
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000275void VerifyVoiceReceiverInfoReport(
276 const StatsReport* report,
277 const cricket::VoiceReceiverInfo& info) {
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000278 std::string value_in_report;
279 EXPECT_TRUE(GetValue(
280 report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281 EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000282 EXPECT_TRUE(GetValue(
283 report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000284 EXPECT_EQ(rtc::ToString<int64>(info.bytes_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000285 EXPECT_TRUE(GetValue(
286 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000287 EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000288 EXPECT_TRUE(GetValue(
289 report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000290 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000291 EXPECT_TRUE(GetValue(
292 report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
293 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000294 EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000295 value_in_report);
296 EXPECT_TRUE(GetValue(
297 report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000298 EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000299 EXPECT_TRUE(GetValue(
300 report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000301 EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000302 EXPECT_TRUE(GetValue(
303 report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000304 EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000305 EXPECT_TRUE(GetValue(
306 report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000307 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000308 value_in_report);
309 EXPECT_TRUE(GetValue(
310 report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311 EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000312 value_in_report);
313 EXPECT_TRUE(GetValue(
314 report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000315 EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000316 EXPECT_TRUE(GetValue(
317 report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000318 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000319 EXPECT_TRUE(GetValue(
320 report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000321 EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000322 EXPECT_TRUE(GetValue(
323 report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000324 EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +0000325 EXPECT_TRUE(GetValue(
326 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000327}
328
329
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000330void VerifyVoiceSenderInfoReport(const StatsReport* report,
331 const cricket::VoiceSenderInfo& sinfo) {
332 std::string value_in_report;
333 EXPECT_TRUE(GetValue(
334 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
335 EXPECT_EQ(sinfo.codec_name, value_in_report);
336 EXPECT_TRUE(GetValue(
337 report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000338 EXPECT_EQ(rtc::ToString<int64>(sinfo.bytes_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000339 EXPECT_TRUE(GetValue(
340 report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000341 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000342 EXPECT_TRUE(GetValue(
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000343 report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000344 EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000345 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000346 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000347 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000348 EXPECT_TRUE(GetValue(
349 report, StatsReport::kStatsValueNameRtt, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000350 EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000351 EXPECT_TRUE(GetValue(
352 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000353 EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000354 EXPECT_TRUE(GetValue(
355 report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
356 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000357 EXPECT_EQ(rtc::ToString<float>(sinfo.aec_quality_min), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000358 EXPECT_TRUE(GetValue(
359 report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000360 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_median_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000361 value_in_report);
362 EXPECT_TRUE(GetValue(
363 report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000364 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_std_ms),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000365 value_in_report);
366 EXPECT_TRUE(GetValue(
367 report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000368 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000369 value_in_report);
370 EXPECT_TRUE(GetValue(
371 report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
372 &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000373 EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss_enhancement),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000374 value_in_report);
375 EXPECT_TRUE(GetValue(
376 report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000377 EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000378 EXPECT_TRUE(GetValue(
379 report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
380 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
381 EXPECT_EQ(typing_detected, value_in_report);
382}
383
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000384// Helper methods to avoid duplication of code.
385void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
386 voice_sender_info->add_ssrc(kSsrcOfTrack);
387 voice_sender_info->codec_name = "fake_codec";
388 voice_sender_info->bytes_sent = 100;
389 voice_sender_info->packets_sent = 101;
390 voice_sender_info->rtt_ms = 102;
391 voice_sender_info->fraction_lost = 103;
392 voice_sender_info->jitter_ms = 104;
393 voice_sender_info->packets_lost = 105;
394 voice_sender_info->ext_seqnum = 106;
395 voice_sender_info->audio_level = 107;
396 voice_sender_info->echo_return_loss = 108;
397 voice_sender_info->echo_return_loss_enhancement = 109;
398 voice_sender_info->echo_delay_median_ms = 110;
399 voice_sender_info->echo_delay_std_ms = 111;
400 voice_sender_info->aec_quality_min = 112.0f;
401 voice_sender_info->typing_noise_detected = false;
402}
403
404void UpdateVoiceSenderInfoFromAudioTrack(
405 FakeAudioTrack* audio_track, cricket::VoiceSenderInfo* voice_sender_info) {
406 audio_track->GetSignalLevel(&voice_sender_info->audio_level);
407 webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
408 audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats);
409 voice_sender_info->typing_noise_detected =
410 audio_processor_stats.typing_noise_detected;
411 voice_sender_info->echo_return_loss = audio_processor_stats.echo_return_loss;
412 voice_sender_info->echo_return_loss_enhancement =
413 audio_processor_stats.echo_return_loss_enhancement;
414 voice_sender_info->echo_delay_median_ms =
415 audio_processor_stats.echo_delay_median_ms;
416 voice_sender_info->aec_quality_min = audio_processor_stats.aec_quality_min;
417 voice_sender_info->echo_delay_std_ms =
418 audio_processor_stats.echo_delay_std_ms;
419}
420
421void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
422 voice_receiver_info->add_ssrc(kSsrcOfTrack);
423 voice_receiver_info->bytes_rcvd = 110;
424 voice_receiver_info->packets_rcvd = 111;
425 voice_receiver_info->packets_lost = 112;
426 voice_receiver_info->fraction_lost = 113;
427 voice_receiver_info->packets_lost = 114;
428 voice_receiver_info->ext_seqnum = 115;
429 voice_receiver_info->jitter_ms = 116;
430 voice_receiver_info->jitter_buffer_ms = 117;
431 voice_receiver_info->jitter_buffer_preferred_ms = 118;
432 voice_receiver_info->delay_estimate_ms = 119;
433 voice_receiver_info->audio_level = 120;
434 voice_receiver_info->expand_rate = 121;
435}
436
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437class StatsCollectorTest : public testing::Test {
438 protected:
439 StatsCollectorTest()
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000440 : media_engine_(new cricket::FakeMediaEngine()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 channel_manager_(
442 new cricket::ChannelManager(media_engine_,
443 new cricket::FakeDeviceManager(),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000444 rtc::Thread::Current())),
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000445 signaling_(channel_manager_.get()),
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000446 session_(channel_manager_.get()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000447 // By default, we ignore session GetStats calls.
448 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false));
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000449 EXPECT_CALL(session_, mediastream_signaling()).WillRepeatedly(
450 Return(&signaling_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000451 }
452
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000453 ~StatsCollectorTest() {}
454
wu@webrtc.org97077a32013-10-25 21:18:33 +0000455 // This creates a standard setup with a transport called "trspname"
456 // having one transport channel
457 // and the specified virtual connection name.
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000458 void InitSessionStats(const std::string& vc_name) {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000459 const std::string kTransportName("trspname");
460 cricket::TransportStats transport_stats;
461 cricket::TransportChannelStats channel_stats;
462 channel_stats.component = 1;
463 transport_stats.content_name = kTransportName;
464 transport_stats.channel_stats.push_back(channel_stats);
465
466 session_stats_.transport_stats[kTransportName] = transport_stats;
467 session_stats_.proxy_to_transport[vc_name] = kTransportName;
468 }
469
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000470 // Adds a outgoing video track with a given SSRC into the stats.
471 void AddOutgoingVideoTrackStats() {
wu@webrtc.org97077a32013-10-25 21:18:33 +0000472 stream_ = webrtc::MediaStream::Create("streamlabel");
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000473 track_= webrtc::VideoTrack::Create(kLocalTrackId, NULL);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000474 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000475 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
476 .WillRepeatedly(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000477 }
478
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000479 // Adds a incoming video track with a given SSRC into the stats.
480 void AddIncomingVideoTrackStats() {
481 stream_ = webrtc::MediaStream::Create("streamlabel");
482 track_= webrtc::VideoTrack::Create(kRemoteTrackId, NULL);
483 stream_->AddTrack(track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000484 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000485 .WillRepeatedly(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000486 }
487
488 // Adds a outgoing audio track with a given SSRC into the stats.
489 void AddOutgoingAudioTrackStats() {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000490 if (stream_ == NULL)
491 stream_ = webrtc::MediaStream::Create("streamlabel");
492
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000493 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000494 kLocalTrackId);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000495 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000496 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000497 .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000498 }
499
500 // Adds a incoming audio track with a given SSRC into the stats.
501 void AddIncomingAudioTrackStats() {
502 if (stream_ == NULL)
503 stream_ = webrtc::MediaStream::Create("streamlabel");
504
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000505 audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000506 kRemoteTrackId);
507 stream_->AddTrack(audio_track_);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000508 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +0000509 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
510 }
511
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000512 std::string AddCandidateReport(StatsCollector* collector,
513 const cricket::Candidate& candidate,
514 const std::string& report_type) {
515 return collector->AddCandidateReport(candidate, report_type);
516 }
517
xians@webrtc.org01bda202014-07-09 07:38:38 +0000518 void SetupAndVerifyAudioTrackStats(
519 FakeAudioTrack* audio_track,
520 webrtc::MediaStream* stream,
521 webrtc::StatsCollector* stats,
522 cricket::VoiceChannel* voice_channel,
523 const std::string& vc_name,
524 MockVoiceMediaChannel* media_channel,
525 cricket::VoiceSenderInfo* voice_sender_info,
526 cricket::VoiceReceiverInfo* voice_receiver_info,
527 cricket::VoiceMediaInfo* stats_read,
528 StatsReports* reports) {
529 // A track can't have both sender report and recv report at the same time
530 // for now, this might change in the future though.
531 ASSERT((voice_sender_info == NULL) ^ (voice_receiver_info == NULL));
xians@webrtc.org01bda202014-07-09 07:38:38 +0000532
533 // Instruct the session to return stats containing the transport channel.
534 InitSessionStats(vc_name);
535 EXPECT_CALL(session_, GetStats(_))
536 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
537 Return(true)));
538
539 // Constructs an ssrc stats update.
540 if (voice_sender_info)
541 stats_read->senders.push_back(*voice_sender_info);
542 if (voice_receiver_info)
543 stats_read->receivers.push_back(*voice_receiver_info);
544
545 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(
546 Return(voice_channel));
547 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
548 EXPECT_CALL(*media_channel, GetStats(_))
549 .WillOnce(DoAll(SetArgPointee<0>(*stats_read), Return(true)));
550
551 stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +0000552 stats->ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +0000553 stats->GetStats(NULL, reports);
554
555 // Verify the existence of the track report.
556 const StatsReport* report = FindNthReportByType(
557 *reports, StatsReport::kStatsReportTypeSsrc, 1);
558 EXPECT_FALSE(report == NULL);
559 std::string track_id = ExtractSsrcStatsValue(
560 *reports, StatsReport::kStatsValueNameTrackId);
561 EXPECT_EQ(audio_track->id(), track_id);
562 std::string ssrc_id = ExtractSsrcStatsValue(
563 *reports, StatsReport::kStatsValueNameSsrc);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000564 EXPECT_EQ(rtc::ToString<uint32>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000565
566 // Verifies the values in the track report.
567 if (voice_sender_info) {
568 UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info);
569 VerifyVoiceSenderInfoReport(report, *voice_sender_info);
570 }
571 if (voice_receiver_info) {
572 VerifyVoiceReceiverInfoReport(report, *voice_receiver_info);
573 }
574
575 // Verify we get the same result by passing a track to GetStats().
576 StatsReports track_reports; // returned values.
577 stats->GetStats(audio_track, &track_reports);
578 const StatsReport* track_report = FindNthReportByType(
579 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
580 EXPECT_TRUE(track_report);
581 track_id = ExtractSsrcStatsValue(track_reports,
582 StatsReport::kStatsValueNameTrackId);
583 EXPECT_EQ(audio_track->id(), track_id);
584 ssrc_id = ExtractSsrcStatsValue(track_reports,
585 StatsReport::kStatsValueNameSsrc);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000586 EXPECT_EQ(rtc::ToString<uint32>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org01bda202014-07-09 07:38:38 +0000587 if (voice_sender_info)
588 VerifyVoiceSenderInfoReport(track_report, *voice_sender_info);
589 if (voice_receiver_info)
590 VerifyVoiceReceiverInfoReport(track_report, *voice_receiver_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000591 }
592
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000593 void TestCertificateReports(const rtc::FakeSSLCertificate& local_cert,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000594 const std::vector<std::string>& local_ders,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000595 const rtc::FakeSSLCertificate& remote_cert,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000596 const std::vector<std::string>& remote_ders) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000597 webrtc::StatsCollector stats(&session_);
598
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000599 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000600
601 // Fake stats to process.
602 cricket::TransportChannelStats channel_stats;
603 channel_stats.component = 1;
604
605 cricket::TransportStats transport_stats;
606 transport_stats.content_name = "audio";
607 transport_stats.channel_stats.push_back(channel_stats);
608
609 cricket::SessionStats session_stats;
610 session_stats.transport_stats[transport_stats.content_name] =
611 transport_stats;
612
613 // Fake certificates to report.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000614 rtc::FakeSSLIdentity local_identity(local_cert);
615 rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert_copy(
wu@webrtc.org4551b792013-10-09 15:37:36 +0000616 remote_cert.GetReference());
617
618 // Fake transport object.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000619 rtc::scoped_ptr<cricket::FakeTransport> transport(
wu@webrtc.org4551b792013-10-09 15:37:36 +0000620 new cricket::FakeTransport(
621 session_.signaling_thread(),
622 session_.worker_thread(),
623 transport_stats.content_name));
624 transport->SetIdentity(&local_identity);
625 cricket::FakeTransportChannel* channel =
626 static_cast<cricket::FakeTransportChannel*>(
627 transport->CreateChannel(channel_stats.component));
628 EXPECT_FALSE(channel == NULL);
629 channel->SetRemoteCertificate(remote_cert_copy.get());
630
631 // Configure MockWebRtcSession
632 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +0000633 .WillRepeatedly(Return(transport.get()));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000634 EXPECT_CALL(session_, GetStats(_))
635 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
636 Return(true)));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000637 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
638 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000639
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000640 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000641
642 stats.GetStats(NULL, &reports);
643
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000644 const StatsReport* channel_report = FindNthReportByType(
645 reports, StatsReport::kStatsReportTypeComponent, 1);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000646 EXPECT_TRUE(channel_report != NULL);
647
648 // Check local certificate chain.
649 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000650 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000651 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000652 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000653 if (local_ders.size() > 0) {
654 EXPECT_NE(kNotFound, local_certificate_id);
655 CheckCertChainReports(reports, local_ders, local_certificate_id);
656 } else {
657 EXPECT_EQ(kNotFound, local_certificate_id);
658 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000659
660 // Check remote certificate chain.
661 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000662 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000663 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000664 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000665 if (remote_ders.size() > 0) {
666 EXPECT_NE(kNotFound, remote_certificate_id);
667 CheckCertChainReports(reports, remote_ders, remote_certificate_id);
668 } else {
669 EXPECT_EQ(kNotFound, remote_certificate_id);
670 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000671 }
wu@webrtc.org97077a32013-10-25 21:18:33 +0000672
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 cricket::FakeMediaEngine* media_engine_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000674 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 MockWebRtcSession session_;
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000676 FakeMediaStreamSignaling signaling_;
677 FakeDataChannelProvider data_channel_provider_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000678 cricket::SessionStats session_stats_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000679 rtc::scoped_refptr<webrtc::MediaStream> stream_;
680 rtc::scoped_refptr<webrtc::VideoTrack> track_;
681 rtc::scoped_refptr<FakeAudioTrack> audio_track_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000682};
683
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000684// Verify that ExtractDataInfo populates reports.
685TEST_F(StatsCollectorTest, ExtractDataInfo) {
686 const std::string label = "hacks";
687 const int id = 31337;
688 const std::string state = DataChannelInterface::DataStateString(
689 DataChannelInterface::DataState::kConnecting);
690
691 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
692 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
693
694 InternalDataChannelInit config;
695 config.id = id;
696 signaling_.AddDataChannel(DataChannel::Create(
697 &data_channel_provider_, cricket::DCT_SCTP, label, config));
698 webrtc::StatsCollector stats(&session_);
699
700 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
701
702 StatsReports reports;
703 stats.GetStats(NULL, &reports);
704 EXPECT_EQ(label, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
705 reports,
706 StatsReport::kStatsValueNameLabel));
707 EXPECT_EQ(rtc::ToString<int64>(id),
708 ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
709 reports,
710 StatsReport::kStatsValueNameDataChannelId));
711 EXPECT_EQ(state, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
712 reports,
713 StatsReport::kStatsValueNameState));
714 EXPECT_EQ("", ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
715 reports,
716 StatsReport::kStatsValueNameProtocol));
717}
718
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719// This test verifies that 64-bit counters are passed successfully.
720TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000721 webrtc::StatsCollector stats(&session_);
722
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000723 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000724 cricket::VideoChannel video_channel(rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 media_engine_, media_channel, &session_, "", false, NULL);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000726 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 cricket::VideoSenderInfo video_sender_info;
728 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 // The number of bytes must be larger than 0xFFFFFFFF for this test.
730 const int64 kBytesSent = 12345678901234LL;
731 const std::string kBytesSentString("12345678901234");
732
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000733 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000734 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000735
736 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000737 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 video_sender_info.bytes_sent = kBytesSent;
739 stats_read.senders.push_back(video_sender_info);
740
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000741 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
742 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000743 EXPECT_CALL(*media_channel, GetStats(_, _))
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000744 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
745 Return(true)));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000746 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000748 std::string result = ExtractSsrcStatsValue(reports,
749 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750 EXPECT_EQ(kBytesSentString, result);
751}
752
753// Test that BWE information is reported via stats.
754TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000755 webrtc::StatsCollector stats(&session_);
756
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000757 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000758 cricket::VideoChannel video_channel(rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759 media_engine_, media_channel, &session_, "", false, NULL);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000760 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 cricket::VideoSenderInfo video_sender_info;
762 cricket::VideoMediaInfo stats_read;
763 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
764 // BWE.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 const int64 kBytesSent = 12345678901234LL;
766 const std::string kBytesSentString("12345678901234");
767
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000768 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000769 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770
771 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000772 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 video_sender_info.bytes_sent = kBytesSent;
774 stats_read.senders.push_back(video_sender_info);
775 cricket::BandwidthEstimationInfo bwe;
776 const int kTargetEncBitrate = 123456;
777 const std::string kTargetEncBitrateString("123456");
778 bwe.target_enc_bitrate = kTargetEncBitrate;
779 stats_read.bw_estimations.push_back(bwe);
780
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000781 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
782 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000783 EXPECT_CALL(*media_channel, GetStats(_, _))
784 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000786
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000787 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 stats.GetStats(NULL, &reports);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000789 std::string result = ExtractSsrcStatsValue(reports,
790 StatsReport::kStatsValueNameBytesSent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 EXPECT_EQ(kBytesSentString, result);
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000792 result = ExtractBweStatsValue(reports,
793 StatsReport::kStatsValueNameTargetEncBitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794 EXPECT_EQ(kTargetEncBitrateString, result);
795}
796
797// This test verifies that an object of type "googSession" always
798// exists in the returned stats.
799TEST_F(StatsCollectorTest, SessionObjectExists) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000800 webrtc::StatsCollector stats(&session_);
801
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000802 StatsReports reports; // returned values.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000803 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
804 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000805 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000807 const StatsReport* session_report = FindNthReportByType(
808 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809 EXPECT_FALSE(session_report == NULL);
810}
811
812// This test verifies that only one object of type "googSession" exists
813// in the returned stats.
814TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000815 webrtc::StatsCollector stats(&session_);
816
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000817 StatsReports reports; // returned values.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000818 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
819 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000820 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
821 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000823 const StatsReport* session_report = FindNthReportByType(
824 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825 EXPECT_FALSE(session_report == NULL);
826 session_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000827 reports, StatsReport::kStatsReportTypeSession, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 EXPECT_EQ(NULL, session_report);
829}
830
831// This test verifies that the empty track report exists in the returned stats
832// without calling StatsCollector::UpdateStats.
833TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000834 webrtc::StatsCollector stats(&session_);
835
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000836 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000837 cricket::VideoChannel video_channel(rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838 media_engine_, media_channel, &session_, "", false, NULL);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000839 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000840 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000842 // Verfies the existence of the track report.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000843 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844 stats.GetStats(NULL, &reports);
845 EXPECT_EQ((size_t)1, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000846 EXPECT_EQ(std::string(StatsReport::kStatsReportTypeTrack),
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000847 reports[0]->type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848
849 std::string trackValue =
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000850 ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000851 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000852 StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000853 EXPECT_EQ(kLocalTrackId, trackValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000854}
855
856// This test verifies that the empty track report exists in the returned stats
857// when StatsCollector::UpdateStats is called with ssrc stats.
858TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000859 webrtc::StatsCollector stats(&session_);
860
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000861 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000862 cricket::VideoChannel video_channel(rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863 media_engine_, media_channel, &session_, "", false, NULL);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000864 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000865 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867 // Constructs an ssrc stats update.
868 cricket::VideoSenderInfo video_sender_info;
869 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870 const int64 kBytesSent = 12345678901234LL;
871
872 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000873 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000874 video_sender_info.bytes_sent = kBytesSent;
875 stats_read.senders.push_back(video_sender_info);
876
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000877 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
878 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000879 EXPECT_CALL(*media_channel, GetStats(_, _))
880 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000883 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000884 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 stats.GetStats(NULL, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000886 // |reports| should contain at least one session report, one track report,
887 // and one ssrc report.
888 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000889 const StatsReport* track_report = FindNthReportByType(
890 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000891 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000893 // Get report for the specific |track|.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +0000894 reports.clear();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000895 stats.GetStats(track_, &reports);
896 // |reports| should contain at least one session report, one track report,
897 // and one ssrc report.
898 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899 track_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000900 reports, StatsReport::kStatsReportTypeTrack, 1);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000901 EXPECT_TRUE(track_report);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000902
903 std::string ssrc_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000904 reports, StatsReport::kStatsValueNameSsrc);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000905 EXPECT_EQ(rtc::ToString<uint32>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000906
907 std::string track_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000908 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000909 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910}
911
912// This test verifies that an SSRC object has the identifier of a Transport
913// stats object, and that this transport stats object exists in stats.
914TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000915 webrtc::StatsCollector stats(&session_);
916
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000917 // Ignore unused callback (logspam).
918 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +0000919 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000920 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921 // The content_name known by the video channel.
922 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000923 cricket::VideoChannel video_channel(rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000924 media_engine_, media_channel, &session_, kVcName, false, NULL);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000925 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000926 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928 // Constructs an ssrc stats update.
929 cricket::VideoSenderInfo video_sender_info;
930 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931 const int64 kBytesSent = 12345678901234LL;
932
933 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000934 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000935 video_sender_info.bytes_sent = kBytesSent;
936 stats_read.senders.push_back(video_sender_info);
937
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000938 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
939 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000940 EXPECT_CALL(*media_channel, GetStats(_, _))
941 .WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943
wu@webrtc.org97077a32013-10-25 21:18:33 +0000944 InitSessionStats(kVcName);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 EXPECT_CALL(session_, GetStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000946 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
947 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000949 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +0000950 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951 stats.GetStats(NULL, &reports);
952 std::string transport_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000953 StatsReport::kStatsReportTypeSsrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000955 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956 ASSERT_NE(kNotFound, transport_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000957 const StatsReport* transport_report = FindReportById(reports,
958 transport_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 ASSERT_FALSE(transport_report == NULL);
960}
961
wu@webrtc.org97077a32013-10-25 21:18:33 +0000962// This test verifies that a remote stats object will not be created for
963// an outgoing SSRC where remote stats are not returned.
964TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000965 webrtc::StatsCollector stats(&session_);
966
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000967 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000968 // The content_name known by the video channel.
969 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000970 cricket::VideoChannel video_channel(rtc::Thread::Current(),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000971 media_engine_, media_channel, &session_, kVcName, false, NULL);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000972 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000973 stats.AddStream(stream_);
974
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000975 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
976 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org97077a32013-10-25 21:18:33 +0000977
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000978 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000979 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000980 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000981 const StatsReport* remote_report = FindNthReportByType(reports,
982 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000983 EXPECT_TRUE(remote_report == NULL);
984}
985
986// This test verifies that a remote stats object will be created for
987// an outgoing SSRC where stats are returned.
988TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000989 webrtc::StatsCollector stats(&session_);
990
tommi@webrtc.org242068d2014-07-14 20:19:56 +0000991 // Ignore unused callback (logspam).
992 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +0000993 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000994 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
wu@webrtc.org97077a32013-10-25 21:18:33 +0000995 // The content_name known by the video channel.
996 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000997 cricket::VideoChannel video_channel(rtc::Thread::Current(),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000998 media_engine_, media_channel, &session_, kVcName, false, NULL);
xians@webrtc.org4cb01282014-06-12 14:57:05 +0000999 AddOutgoingVideoTrackStats();
wu@webrtc.org97077a32013-10-25 21:18:33 +00001000 stats.AddStream(stream_);
1001
wu@webrtc.org97077a32013-10-25 21:18:33 +00001002 // Instruct the session to return stats containing the transport channel.
1003 InitSessionStats(kVcName);
1004 EXPECT_CALL(session_, GetStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001005 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1006 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001007
1008 // Constructs an ssrc stats update.
1009 cricket::VideoMediaInfo stats_read;
1010
1011 cricket::SsrcReceiverInfo remote_ssrc_stats;
1012 remote_ssrc_stats.timestamp = 12345.678;
1013 remote_ssrc_stats.ssrc = kSsrcOfTrack;
1014 cricket::VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001015 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001016 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
1017 stats_read.senders.push_back(video_sender_info);
1018
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001019 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1020 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001021 EXPECT_CALL(*media_channel, GetStats(_, _))
1022 .WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
wu@webrtc.org97077a32013-10-25 21:18:33 +00001023 Return(true)));
1024
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001025 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001026 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001027 stats.GetStats(NULL, &reports);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001028
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001029 const StatsReport* remote_report = FindNthReportByType(reports,
1030 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +00001031 EXPECT_FALSE(remote_report == NULL);
1032 EXPECT_NE(0, remote_report->timestamp);
1033}
1034
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001035// This test verifies that the empty track report exists in the returned stats
1036// when StatsCollector::UpdateStats is called with ssrc stats.
1037TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001038 webrtc::StatsCollector stats(&session_);
1039
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001040 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001041 cricket::VideoChannel video_channel(rtc::Thread::Current(),
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001042 media_engine_, media_channel, &session_, "", false, NULL);
1043 AddIncomingVideoTrackStats();
1044 stats.AddStream(stream_);
1045
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001046 // Constructs an ssrc stats update.
1047 cricket::VideoReceiverInfo video_receiver_info;
1048 cricket::VideoMediaInfo stats_read;
1049 const int64 kNumOfPacketsConcealed = 54321;
1050
1051 // Construct a stats value to read.
1052 video_receiver_info.add_ssrc(1234);
1053 video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
1054 stats_read.receivers.push_back(video_receiver_info);
1055
1056 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
1057 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
1058 EXPECT_CALL(*media_channel, GetStats(_, _))
1059 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
1060 Return(true)));
1061
1062 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001063 StatsReports reports;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001064 stats.GetStats(NULL, &reports);
1065 // |reports| should contain at least one session report, one track report,
1066 // and one ssrc report.
1067 EXPECT_LE(static_cast<size_t>(3), reports.size());
1068 const StatsReport* track_report = FindNthReportByType(
1069 reports, StatsReport::kStatsReportTypeTrack, 1);
1070 EXPECT_TRUE(track_report);
1071
1072 std::string ssrc_id = ExtractSsrcStatsValue(
1073 reports, StatsReport::kStatsValueNameSsrc);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001074 EXPECT_EQ(rtc::ToString<uint32>(kSsrcOfTrack), ssrc_id);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001075
1076 std::string track_id = ExtractSsrcStatsValue(
1077 reports, StatsReport::kStatsValueNameTrackId);
1078 EXPECT_EQ(kRemoteTrackId, track_id);
1079}
1080
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001081// This test verifies the Ice Candidate report should contain the correct
1082// information from local/remote candidates.
1083TEST_F(StatsCollectorTest, IceCandidateReport) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001084 webrtc::StatsCollector stats(&session_);
1085
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001086 StatsReports reports; // returned values.
1087
1088 const int local_port = 2000;
1089 const char local_ip[] = "192.168.0.1";
1090 const int remote_port = 2001;
1091 const char remote_ip[] = "192.168.0.2";
1092
1093 rtc::SocketAddress local_address(local_ip, local_port);
1094 rtc::SocketAddress remote_address(remote_ip, remote_port);
1095 rtc::AdapterType network_type = rtc::ADAPTER_TYPE_ETHERNET;
1096 uint32 priority = 1000;
1097
1098 cricket::Candidate c;
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001099 ASSERT(c.id().length() > 0);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001100 c.set_type(cricket::LOCAL_PORT_TYPE);
1101 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
1102 c.set_address(local_address);
1103 c.set_priority(priority);
1104 c.set_network_type(network_type);
1105 std::string report_id = AddCandidateReport(
1106 &stats, c, StatsReport::kStatsReportTypeIceLocalCandidate);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001107 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001108
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001109 c = cricket::Candidate();
1110 ASSERT(c.id().length() > 0);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001111 c.set_type(cricket::PRFLX_PORT_TYPE);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001112 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001113 c.set_address(remote_address);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001114 c.set_priority(priority);
1115 c.set_network_type(network_type);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001116 report_id = AddCandidateReport(
1117 &stats, c, StatsReport::kStatsReportTypeIceRemoteCandidate);
guoweis@webrtc.org61c12472015-01-15 06:53:07 +00001118 EXPECT_EQ("Cand-" + c.id(), report_id);
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001119
1120 stats.GetStats(NULL, &reports);
1121
1122 // Verify the local candidate report is populated correctly.
1123 EXPECT_EQ(
1124 local_ip,
1125 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1126 StatsReport::kStatsValueNameCandidateIPAddress));
1127 EXPECT_EQ(
1128 rtc::ToString<int>(local_port),
1129 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1130 StatsReport::kStatsValueNameCandidatePortNumber));
1131 EXPECT_EQ(
1132 cricket::UDP_PROTOCOL_NAME,
1133 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1134 StatsReport::kStatsValueNameCandidateTransportType));
1135 EXPECT_EQ(
1136 rtc::ToString<int>(priority),
1137 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1138 StatsReport::kStatsValueNameCandidatePriority));
1139 EXPECT_EQ(
1140 IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
1141 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1142 StatsReport::kStatsValueNameCandidateType));
1143 EXPECT_EQ(
1144 AdapterTypeToStatsType(network_type),
1145 ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
1146 StatsReport::kStatsValueNameCandidateNetworkType));
1147
1148 // Verify the remote candidate report is populated correctly.
1149 EXPECT_EQ(remote_ip,
1150 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1151 reports,
1152 StatsReport::kStatsValueNameCandidateIPAddress));
1153 EXPECT_EQ(rtc::ToString<int>(remote_port),
1154 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1155 reports,
1156 StatsReport::kStatsValueNameCandidatePortNumber));
1157 EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
1158 ExtractStatsValue(
1159 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1160 StatsReport::kStatsValueNameCandidateTransportType));
1161 EXPECT_EQ(rtc::ToString<int>(priority),
1162 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1163 reports,
1164 StatsReport::kStatsValueNameCandidatePriority));
1165 EXPECT_EQ(
1166 IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
1167 ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
1168 reports, StatsReport::kStatsValueNameCandidateType));
1169 EXPECT_EQ(kNotFound,
1170 ExtractStatsValue(
1171 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
1172 StatsReport::kStatsValueNameCandidateNetworkType));
1173}
1174
wu@webrtc.org4551b792013-10-09 15:37:36 +00001175// This test verifies that all chained certificates are correctly
1176// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001177TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001178 // Build local certificate chain.
1179 std::vector<std::string> local_ders(5);
1180 local_ders[0] = "These";
1181 local_ders[1] = "are";
1182 local_ders[2] = "some";
1183 local_ders[3] = "der";
1184 local_ders[4] = "values";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001185 rtc::FakeSSLCertificate local_cert(DersToPems(local_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001186
1187 // Build remote certificate chain
1188 std::vector<std::string> remote_ders(4);
1189 remote_ders[0] = "A";
1190 remote_ders[1] = "non-";
1191 remote_ders[2] = "intersecting";
1192 remote_ders[3] = "set";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001193 rtc::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001194
1195 TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
1196}
1197
1198// This test verifies that all certificates without chains are correctly
1199// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001200TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +00001201 // Build local certificate.
1202 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001203 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001204
1205 // Build remote certificate.
1206 std::string remote_der = "This is somebody else's der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001207 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001208
1209 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
1210 remote_cert, std::vector<std::string>(1, remote_der));
1211}
1212
1213// This test verifies that the stats are generated correctly when no
1214// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001215TEST_F(StatsCollectorTest, NoTransport) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001216 webrtc::StatsCollector stats(&session_);
1217
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001218 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001219
1220 // Fake stats to process.
1221 cricket::TransportChannelStats channel_stats;
1222 channel_stats.component = 1;
1223
1224 cricket::TransportStats transport_stats;
1225 transport_stats.content_name = "audio";
1226 transport_stats.channel_stats.push_back(channel_stats);
1227
1228 cricket::SessionStats session_stats;
1229 session_stats.transport_stats[transport_stats.content_name] =
1230 transport_stats;
1231
1232 // Configure MockWebRtcSession
1233 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001234 .WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +00001235 EXPECT_CALL(session_, GetStats(_))
1236 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
1237 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001238
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001239 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1240 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +00001241
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001242 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001243 stats.GetStats(NULL, &reports);
1244
1245 // Check that the local certificate is absent.
1246 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001247 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001248 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001249 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001250 ASSERT_EQ(kNotFound, local_certificate_id);
1251
1252 // Check that the remote certificate is absent.
1253 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001254 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001255 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001256 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001257 ASSERT_EQ(kNotFound, remote_certificate_id);
1258}
1259
1260// This test verifies that the stats are generated correctly when the transport
1261// does not have any certificates.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001262TEST_F(StatsCollectorTest, NoCertificates) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001263 webrtc::StatsCollector stats(&session_);
1264
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001265 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +00001266
1267 // Fake stats to process.
1268 cricket::TransportChannelStats channel_stats;
1269 channel_stats.component = 1;
1270
1271 cricket::TransportStats transport_stats;
1272 transport_stats.content_name = "audio";
1273 transport_stats.channel_stats.push_back(channel_stats);
1274
1275 cricket::SessionStats session_stats;
1276 session_stats.transport_stats[transport_stats.content_name] =
1277 transport_stats;
1278
1279 // Fake transport object.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001280 rtc::scoped_ptr<cricket::FakeTransport> transport(
wu@webrtc.org4551b792013-10-09 15:37:36 +00001281 new cricket::FakeTransport(
1282 session_.signaling_thread(),
1283 session_.worker_thread(),
1284 transport_stats.content_name));
1285
1286 // Configure MockWebRtcSession
1287 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001288 .WillRepeatedly(Return(transport.get()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00001289 EXPECT_CALL(session_, GetStats(_))
1290 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
1291 Return(true)));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001292 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1293 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +00001294
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001295 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001296 stats.GetStats(NULL, &reports);
1297
1298 // Check that the local certificate is absent.
1299 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001300 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001301 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001302 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001303 ASSERT_EQ(kNotFound, local_certificate_id);
1304
1305 // Check that the remote certificate is absent.
1306 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001307 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +00001308 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001309 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +00001310 ASSERT_EQ(kNotFound, remote_certificate_id);
1311}
1312
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001313// This test verifies that a remote certificate with an unsupported digest
1314// algorithm is correctly ignored.
1315TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
1316 // Build a local certificate.
1317 std::string local_der = "This is the local der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001318 rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001319
1320 // Build a remote certificate with an unsupported digest algorithm.
1321 std::string remote_der = "This is somebody else's der.";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001322 rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001323 remote_cert.set_digest_algorithm("foobar");
1324
1325 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
1326 remote_cert, std::vector<std::string>());
1327}
1328
1329// Verifies the correct optons are passed to the VideoMediaChannel when using
1330// verbose output level.
1331TEST_F(StatsCollectorTest, StatsOutputLevelVerbose) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001332 webrtc::StatsCollector stats(&session_);
1333
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001334 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001335 cricket::VideoChannel video_channel(rtc::Thread::Current(),
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001336 media_engine_, media_channel, &session_, "", false, NULL);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001337
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001338 cricket::VideoMediaInfo stats_read;
1339 cricket::BandwidthEstimationInfo bwe;
1340 bwe.total_received_propagation_delta_ms = 10;
1341 bwe.recent_received_propagation_delta_ms.push_back(100);
1342 bwe.recent_received_propagation_delta_ms.push_back(200);
1343 bwe.recent_received_packet_group_arrival_time_ms.push_back(1000);
1344 bwe.recent_received_packet_group_arrival_time_ms.push_back(2000);
1345 stats_read.bw_estimations.push_back(bwe);
1346
1347 EXPECT_CALL(session_, video_channel())
1348 .WillRepeatedly(Return(&video_channel));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001349 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001350
1351 StatsOptions options;
1352 options.include_received_propagation_stats = true;
1353 EXPECT_CALL(*media_channel, GetStats(
1354 Field(&StatsOptions::include_received_propagation_stats, true),
1355 _))
1356 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
1357 Return(true)));
1358
1359 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelDebug);
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001360 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001361 stats.GetStats(NULL, &reports);
1362 std::string result = ExtractBweStatsValue(
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001363 reports,
1364 StatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaSumDebug);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001365 EXPECT_EQ("10", result);
1366 result = ExtractBweStatsValue(
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001367 reports,
1368 StatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaDebug);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001369 EXPECT_EQ("[100, 200]", result);
1370 result = ExtractBweStatsValue(
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001371 reports, StatsReport::kStatsValueNameRecvPacketGroupArrivalTimeDebug);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001372 EXPECT_EQ("[1000, 2000]", result);
1373}
1374
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001375// This test verifies that a local stats object can get statistics via
1376// AudioTrackInterface::GetStats() method.
1377TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001378 webrtc::StatsCollector stats(&session_);
1379
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001380 // Ignore unused callback (logspam).
1381 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001382 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001383
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001384 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1385 // The content_name known by the voice channel.
1386 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001387 cricket::VoiceChannel voice_channel(rtc::Thread::Current(),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001388 media_engine_, media_channel, &session_, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001389 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001390 stats.AddStream(stream_);
xians@webrtc.org01bda202014-07-09 07:38:38 +00001391 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001392
1393 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001394 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001395
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001396 cricket::VoiceMediaInfo stats_read;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001397 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001398 SetupAndVerifyAudioTrackStats(
1399 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1400 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001401
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001402 // Verify that there is no remote report for the local audio track because
1403 // we did not set it up.
1404 const StatsReport* remote_report = FindNthReportByType(reports,
1405 StatsReport::kStatsReportTypeRemoteSsrc, 1);
1406 EXPECT_TRUE(remote_report == NULL);
1407}
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001408
1409// This test verifies that audio receive streams populate stats reports
1410// correctly.
1411TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001412 webrtc::StatsCollector stats(&session_);
1413
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001414 // Ignore unused callback (logspam).
1415 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001416 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001417 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1418 // The content_name known by the voice channel.
1419 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001420 cricket::VoiceChannel voice_channel(rtc::Thread::Current(),
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001421 media_engine_, media_channel, &session_, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001422 AddIncomingAudioTrackStats();
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001423 stats.AddStream(stream_);
1424
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001425 cricket::VoiceReceiverInfo voice_receiver_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001426 InitVoiceReceiverInfo(&voice_receiver_info);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001427 voice_receiver_info.codec_name = "fake_codec";
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001428
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001429 cricket::VoiceMediaInfo stats_read;
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001430 StatsReports reports; // returned values.
xians@webrtc.org01bda202014-07-09 07:38:38 +00001431 SetupAndVerifyAudioTrackStats(
1432 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1433 media_channel, NULL, &voice_receiver_info, &stats_read, &reports);
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001434}
1435
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001436// This test verifies that a local stats object won't update its statistics
1437// after a RemoveLocalAudioTrack() call.
1438TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001439 webrtc::StatsCollector stats(&session_);
1440
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001441 // Ignore unused callback (logspam).
1442 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001443 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001444 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1445 // The content_name known by the voice channel.
1446 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001447 cricket::VoiceChannel voice_channel(rtc::Thread::Current(),
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001448 media_engine_, media_channel, &session_, kVcName, false);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001449 AddOutgoingAudioTrackStats();
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001450 stats.AddStream(stream_);
1451 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1452
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001453 // Instruct the session to return stats containing the transport channel.
1454 InitSessionStats(kVcName);
1455 EXPECT_CALL(session_, GetStats(_))
1456 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1457 Return(true)));
1458
1459 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1460 cricket::VoiceSenderInfo voice_sender_info;
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001461 InitVoiceSenderInfo(&voice_sender_info);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001462
1463 // Constructs an ssrc stats update.
1464 cricket::VoiceMediaInfo stats_read;
1465 stats_read.senders.push_back(voice_sender_info);
1466
1467 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1468 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1469 EXPECT_CALL(*media_channel, GetStats(_))
1470 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1471 Return(true)));
1472
1473 StatsReports reports; // returned values.
1474 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1475 stats.GetStats(NULL, &reports);
1476
1477 // The report will exist since we don't remove them in RemoveStream().
1478 const StatsReport* report = FindNthReportByType(
1479 reports, StatsReport::kStatsReportTypeSsrc, 1);
1480 EXPECT_FALSE(report == NULL);
1481 std::string track_id = ExtractSsrcStatsValue(
1482 reports, StatsReport::kStatsValueNameTrackId);
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001483 EXPECT_EQ(kLocalTrackId, track_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001484 std::string ssrc_id = ExtractSsrcStatsValue(
1485 reports, StatsReport::kStatsValueNameSsrc);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001486 EXPECT_EQ(rtc::ToString<uint32>(kSsrcOfTrack), ssrc_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001487
1488 // Verifies the values in the track report, no value will be changed by the
1489 // AudioTrackInterface::GetSignalValue() and
1490 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1491 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1492}
1493
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001494// This test verifies that when ongoing and incoming audio tracks are using
1495// the same ssrc, they populate stats reports correctly.
1496TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001497 webrtc::StatsCollector stats(&session_);
1498
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001499 // Ignore unused callback (logspam).
1500 EXPECT_CALL(session_, GetTransport(_))
jiayl@webrtc.org06b04ec2014-07-24 20:41:20 +00001501 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001502 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1503 // The content_name known by the voice channel.
1504 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001505 cricket::VoiceChannel voice_channel(rtc::Thread::Current(),
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001506 media_engine_, media_channel, &session_, kVcName, false);
1507
1508 // Create a local stream with a local audio track and adds it to the stats.
1509 AddOutgoingAudioTrackStats();
1510 stats.AddStream(stream_);
1511 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1512
1513 // Create a remote stream with a remote audio track and adds it to the stats.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001514 rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001515 webrtc::MediaStream::Create("remotestreamlabel"));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001516 rtc::scoped_refptr<FakeAudioTrack> remote_track(
1517 new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001518 EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
xians@webrtc.org01bda202014-07-09 07:38:38 +00001519 .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001520 remote_stream->AddTrack(remote_track);
1521 stats.AddStream(remote_stream);
1522
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001523 // Instruct the session to return stats containing the transport channel.
1524 InitSessionStats(kVcName);
1525 EXPECT_CALL(session_, GetStats(_))
1526 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1527 Return(true)));
1528
1529 cricket::VoiceSenderInfo voice_sender_info;
1530 InitVoiceSenderInfo(&voice_sender_info);
1531
1532 // Some of the contents in |voice_sender_info| needs to be updated from the
1533 // |audio_track_|.
1534 UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info);
1535
1536 cricket::VoiceReceiverInfo voice_receiver_info;
1537 InitVoiceReceiverInfo(&voice_receiver_info);
1538
1539 // Constructs an ssrc stats update.
1540 cricket::VoiceMediaInfo stats_read;
1541 stats_read.senders.push_back(voice_sender_info);
1542 stats_read.receivers.push_back(voice_receiver_info);
1543
1544 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1545 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1546 EXPECT_CALL(*media_channel, GetStats(_))
1547 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1548 Return(true)));
1549
1550 StatsReports reports; // returned values.
1551 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1552
1553 // Get stats for the local track.
1554 stats.GetStats(audio_track_.get(), &reports);
1555 const StatsReport* track_report = FindNthReportByType(
1556 reports, StatsReport::kStatsReportTypeSsrc, 1);
1557 EXPECT_TRUE(track_report);
1558 std::string track_id = ExtractSsrcStatsValue(
1559 reports, StatsReport::kStatsValueNameTrackId);
1560 EXPECT_EQ(kLocalTrackId, track_id);
1561 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1562
1563 // Get stats for the remote track.
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001564 reports.clear();
xians@webrtc.org4cb01282014-06-12 14:57:05 +00001565 stats.GetStats(remote_track.get(), &reports);
1566 track_report = FindNthReportByType(reports,
1567 StatsReport::kStatsReportTypeSsrc, 1);
1568 EXPECT_TRUE(track_report);
1569 track_id = ExtractSsrcStatsValue(reports,
1570 StatsReport::kStatsValueNameTrackId);
1571 EXPECT_EQ(kRemoteTrackId, track_id);
1572 VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
1573}
1574
xians@webrtc.org01bda202014-07-09 07:38:38 +00001575// This test verifies that when two outgoing audio tracks are using the same
1576// ssrc at different times, they populate stats reports correctly.
1577// TODO(xians): Figure out if it is possible to encapsulate the setup and
1578// avoid duplication of code in test cases.
1579TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) {
decurtis@webrtc.org487a4442015-01-15 22:55:07 +00001580 webrtc::StatsCollector stats(&session_);
1581
tommi@webrtc.org242068d2014-07-14 20:19:56 +00001582 // Ignore unused callback (logspam).
1583 EXPECT_CALL(session_, GetTransport(_))
1584 .WillRepeatedly(Return(static_cast<cricket::Transport*>(NULL)));
xians@webrtc.org01bda202014-07-09 07:38:38 +00001585 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1586 // The content_name known by the voice channel.
1587 const std::string kVcName("vcname");
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001588 cricket::VoiceChannel voice_channel(rtc::Thread::Current(),
xians@webrtc.org01bda202014-07-09 07:38:38 +00001589 media_engine_, media_channel, &session_, kVcName, false);
1590
1591 // Create a local stream with a local audio track and adds it to the stats.
1592 AddOutgoingAudioTrackStats();
1593 stats.AddStream(stream_);
1594 stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
1595
1596 cricket::VoiceSenderInfo voice_sender_info;
1597 voice_sender_info.add_ssrc(kSsrcOfTrack);
1598
1599 cricket::VoiceMediaInfo stats_read;
1600 StatsReports reports; // returned values.
1601 SetupAndVerifyAudioTrackStats(
1602 audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
1603 media_channel, &voice_sender_info, NULL, &stats_read, &reports);
1604
1605 // Remove the previous audio track from the stream.
1606 stream_->RemoveTrack(audio_track_.get());
1607 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1608
1609 // Create a new audio track and adds it to the stream and stats.
1610 static const std::string kNewTrackId = "new_track_id";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001611 rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
1612 new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
xians@webrtc.org01bda202014-07-09 07:38:38 +00001613 EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
1614 .WillOnce(DoAll(SetArgPointee<1>(kNewTrackId), Return(true)));
1615 stream_->AddTrack(new_audio_track);
1616
1617 stats.AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
tommi@webrtc.org69bc5a32014-12-15 09:44:48 +00001618 stats.ClearUpdateStatsCacheForTest();
xians@webrtc.org01bda202014-07-09 07:38:38 +00001619 cricket::VoiceSenderInfo new_voice_sender_info;
1620 InitVoiceSenderInfo(&new_voice_sender_info);
1621 cricket::VoiceMediaInfo new_stats_read;
tommi@webrtc.org5b06b062014-08-15 08:38:30 +00001622 reports.clear();
xians@webrtc.org01bda202014-07-09 07:38:38 +00001623 SetupAndVerifyAudioTrackStats(
1624 new_audio_track.get(), stream_.get(), &stats, &voice_channel, kVcName,
1625 media_channel, &new_voice_sender_info, NULL, &new_stats_read, &reports);
1626}
1627
guoweis@webrtc.org950c5182014-12-16 23:01:31 +00001628} // namespace webrtc