blob: fb559697152bb364d226e5ff3d2373c8ba0884d5 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <stdio.h>
28
29#include "talk/app/webrtc/statscollector.h"
30
31#include "talk/app/webrtc/mediastream.h"
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000032#include "talk/app/webrtc/mediastreaminterface.h"
33#include "talk/app/webrtc/mediastreamtrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/app/webrtc/videotrack.h"
wu@webrtc.org4551b792013-10-09 15:37:36 +000035#include "talk/base/base64.h"
36#include "talk/base/fakesslidentity.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037#include "talk/base/gunit.h"
38#include "talk/media/base/fakemediaengine.h"
39#include "talk/media/devices/fakedevicemanager.h"
40#include "talk/p2p/base/fakesession.h"
41#include "talk/session/media/channelmanager.h"
42#include "testing/base/public/gmock.h"
43
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000044using cricket::StatsOptions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045using testing::_;
46using testing::DoAll;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000047using testing::Field;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048using testing::Return;
49using testing::ReturnNull;
50using testing::SetArgPointee;
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000051using webrtc::PeerConnectionInterface;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000052using webrtc::StatsReport;
53using webrtc::StatsReports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
55namespace cricket {
56
57class ChannelManager;
58class FakeDeviceManager;
59
60} // namespace cricket
61
62namespace {
63
64// Error return values
65const char kNotFound[] = "NOT FOUND";
66const char kNoReports[] = "NO REPORTS";
67
wu@webrtc.org97077a32013-10-25 21:18:33 +000068// Constant names for track identification.
69const char kTrackId[] = "somename";
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000070const char kAudioTrackId[] = "audio_track_id";
wu@webrtc.org97077a32013-10-25 21:18:33 +000071const uint32 kSsrcOfTrack = 1234;
72
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073class MockWebRtcSession : public webrtc::WebRtcSession {
74 public:
75 explicit MockWebRtcSession(cricket::ChannelManager* channel_manager)
76 : WebRtcSession(channel_manager, talk_base::Thread::Current(),
wu@webrtc.org4551b792013-10-09 15:37:36 +000077 talk_base::Thread::Current(), NULL, NULL) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 }
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000079 MOCK_METHOD0(voice_channel, cricket::VoiceChannel*());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 MOCK_METHOD0(video_channel, cricket::VideoChannel*());
81 MOCK_METHOD2(GetTrackIdBySsrc, bool(uint32, std::string*));
82 MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
wu@webrtc.org4551b792013-10-09 15:37:36 +000083 MOCK_METHOD1(GetTransport, cricket::Transport*(const std::string&));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084};
85
86class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
87 public:
88 MockVideoMediaChannel()
89 : cricket::FakeVideoMediaChannel(NULL) {
90 }
91 // MOCK_METHOD0(transport_channel, cricket::TransportChannel*());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000092 MOCK_METHOD2(GetStats, bool(const StatsOptions&, cricket::VideoMediaInfo*));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093};
94
henrike@webrtc.org40b3b682014-03-03 18:30:11 +000095class MockVoiceMediaChannel : public cricket::FakeVoiceMediaChannel {
96 public:
97 MockVoiceMediaChannel() : cricket::FakeVoiceMediaChannel(NULL) {
98 }
99 MOCK_METHOD1(GetStats, bool(cricket::VoiceMediaInfo*));
100};
101
102class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
103 public:
104 FakeAudioProcessor() {}
105 ~FakeAudioProcessor() {}
106
107 private:
108 virtual void GetStats(
109 AudioProcessorInterface::AudioProcessorStats* stats) OVERRIDE {
110 stats->typing_noise_detected = true;
111 stats->echo_return_loss = 2;
112 stats->echo_return_loss_enhancement = 3;
113 stats->echo_delay_median_ms = 4;
114 stats->aec_quality_min = 5.1f;
115 stats->echo_delay_std_ms = 6;
116 }
117};
118
119class FakeLocalAudioTrack
120 : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
121 public:
122 explicit FakeLocalAudioTrack(const std::string& id)
123 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
124 processor_(new talk_base::RefCountedObject<FakeAudioProcessor>()) {}
125 std::string kind() const OVERRIDE {
126 return "audio";
127 }
128 virtual webrtc::AudioSourceInterface* GetSource() const OVERRIDE {
129 return NULL;
130 }
131 virtual void AddSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
132 virtual void RemoveSink(webrtc::AudioTrackSinkInterface* sink) OVERRIDE {}
133 virtual bool GetSignalLevel(int* level) OVERRIDE {
134 *level = 1;
135 return true;
136 }
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000137 virtual talk_base::scoped_refptr<webrtc::AudioProcessorInterface>
138 GetAudioProcessor() OVERRIDE {
139 return processor_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000140 }
141
142 private:
143 talk_base::scoped_refptr<FakeAudioProcessor> processor_;
144};
145
146bool GetValue(const StatsReport* report,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000147 const std::string& name,
148 std::string* value) {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000149 StatsReport::Values::const_iterator it = report->values.begin();
wu@webrtc.org4551b792013-10-09 15:37:36 +0000150 for (; it != report->values.end(); ++it) {
151 if (it->name == name) {
152 *value = it->value;
153 return true;
154 }
155 }
156 return false;
157}
158
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000159std::string ExtractStatsValue(const std::string& type,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000160 const StatsReports& reports,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 const std::string name) {
162 if (reports.empty()) {
163 return kNoReports;
164 }
165 for (size_t i = 0; i < reports.size(); ++i) {
166 if (reports[i].type != type)
167 continue;
wu@webrtc.org4551b792013-10-09 15:37:36 +0000168 std::string ret;
169 if (GetValue(&reports[i], name, &ret)) {
170 return ret;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 }
172 }
173
174 return kNotFound;
175}
176
177// Finds the |n|-th report of type |type| in |reports|.
178// |n| starts from 1 for finding the first report.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000179const StatsReport* FindNthReportByType(
180 const StatsReports& reports, const std::string& type, int n) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 for (size_t i = 0; i < reports.size(); ++i) {
182 if (reports[i].type == type) {
183 n--;
184 if (n == 0)
185 return &reports[i];
186 }
187 }
188 return NULL;
189}
190
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000191const StatsReport* FindReportById(const StatsReports& reports,
192 const std::string& id) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 for (size_t i = 0; i < reports.size(); ++i) {
194 if (reports[i].id == id) {
195 return &reports[i];
196 }
197 }
198 return NULL;
199}
200
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000201std::string ExtractSsrcStatsValue(StatsReports reports,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 const std::string& name) {
203 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000204 StatsReport::kStatsReportTypeSsrc, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205}
206
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000207std::string ExtractBweStatsValue(StatsReports reports,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 const std::string& name) {
209 return ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000210 StatsReport::kStatsReportTypeBwe, reports, name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211}
212
wu@webrtc.org4551b792013-10-09 15:37:36 +0000213std::string DerToPem(const std::string& der) {
214 return talk_base::SSLIdentity::DerToPem(
215 talk_base::kPemTypeCertificate,
216 reinterpret_cast<const unsigned char*>(der.c_str()),
217 der.length());
218}
219
220std::vector<std::string> DersToPems(
221 const std::vector<std::string>& ders) {
222 std::vector<std::string> pems(ders.size());
223 std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
224 return pems;
225}
226
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000227void CheckCertChainReports(const StatsReports& reports,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000228 const std::vector<std::string>& ders,
229 const std::string& start_id) {
230 std::string certificate_id = start_id;
231 size_t i = 0;
232 while (true) {
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000233 const StatsReport* report = FindReportById(reports, certificate_id);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000234 ASSERT_TRUE(report != NULL);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000235
wu@webrtc.org4551b792013-10-09 15:37:36 +0000236 std::string der_base64;
237 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000238 report, StatsReport::kStatsValueNameDer, &der_base64));
wu@webrtc.org4551b792013-10-09 15:37:36 +0000239 std::string der = talk_base::Base64::Decode(der_base64,
240 talk_base::Base64::DO_STRICT);
241 EXPECT_EQ(ders[i], der);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000242
243 std::string fingerprint_algorithm;
244 EXPECT_TRUE(GetValue(
245 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000246 StatsReport::kStatsValueNameFingerprintAlgorithm,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000247 &fingerprint_algorithm));
248 // The digest algorithm for a FakeSSLCertificate is always SHA-1.
249 std::string sha_1_str = talk_base::DIGEST_SHA_1;
250 EXPECT_EQ(sha_1_str, fingerprint_algorithm);
251
252 std::string dummy_fingerprint; // Value is not checked.
253 EXPECT_TRUE(GetValue(
254 report,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000255 StatsReport::kStatsValueNameFingerprint,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000256 &dummy_fingerprint));
257
wu@webrtc.org4551b792013-10-09 15:37:36 +0000258 ++i;
259 if (!GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000260 report, StatsReport::kStatsValueNameIssuerId, &certificate_id))
wu@webrtc.org4551b792013-10-09 15:37:36 +0000261 break;
262 }
263 EXPECT_EQ(ders.size(), i);
264}
265
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +0000266void VerifyVoiceReceiverInfoReport(const StatsReport* report,
267 const cricket::VoiceReceiverInfo& sinfo) {
268 std::string value_in_report;
269 EXPECT_TRUE(GetValue(
270 report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
271 EXPECT_EQ(talk_base::ToString<int>(sinfo.audio_level), value_in_report);
272 EXPECT_TRUE(GetValue(
273 report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
274 EXPECT_EQ(talk_base::ToString<int>(sinfo.bytes_rcvd), value_in_report);
275 EXPECT_TRUE(GetValue(
276 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
277 EXPECT_EQ(talk_base::ToString<int>(sinfo.jitter_ms), value_in_report);
278 EXPECT_TRUE(GetValue(
279 report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
280 EXPECT_EQ(talk_base::ToString<int>(sinfo.jitter_buffer_ms), value_in_report);
281 EXPECT_TRUE(GetValue(
282 report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
283 &value_in_report));
284 EXPECT_EQ(talk_base::ToString<int>(sinfo.jitter_buffer_preferred_ms),
285 value_in_report);
286 EXPECT_TRUE(GetValue(
287 report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
288 EXPECT_EQ(talk_base::ToString<int>(sinfo.delay_estimate_ms), value_in_report);
289 EXPECT_TRUE(GetValue(
290 report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
291 EXPECT_EQ(talk_base::ToString<float>(sinfo.expand_rate), value_in_report);
292 EXPECT_TRUE(GetValue(
293 report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
294 EXPECT_EQ(talk_base::ToString<int>(sinfo.packets_rcvd), value_in_report);
295 EXPECT_TRUE(GetValue(
296 report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
297 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_calls_to_silence_generator),
298 value_in_report);
299 EXPECT_TRUE(GetValue(
300 report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
301 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_calls_to_neteq),
302 value_in_report);
303 EXPECT_TRUE(GetValue(
304 report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
305 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_normal), value_in_report);
306 EXPECT_TRUE(GetValue(
307 report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
308 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_plc), value_in_report);
309 EXPECT_TRUE(GetValue(
310 report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
311 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_cng), value_in_report);
312 EXPECT_TRUE(GetValue(
313 report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
314 EXPECT_EQ(talk_base::ToString<int>(sinfo.decoding_plc_cng), value_in_report);
315}
316
317
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000318void VerifyVoiceSenderInfoReport(const StatsReport* report,
319 const cricket::VoiceSenderInfo& sinfo) {
320 std::string value_in_report;
321 EXPECT_TRUE(GetValue(
322 report, StatsReport::kStatsValueNameCodecName, &value_in_report));
323 EXPECT_EQ(sinfo.codec_name, value_in_report);
324 EXPECT_TRUE(GetValue(
325 report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
326 EXPECT_EQ(talk_base::ToString<int64>(sinfo.bytes_sent), value_in_report);
327 EXPECT_TRUE(GetValue(
328 report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
329 EXPECT_EQ(talk_base::ToString<int>(sinfo.packets_sent), value_in_report);
330 EXPECT_TRUE(GetValue(
henrike@webrtc.orgffe26202014-03-19 22:20:10 +0000331 report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
332 EXPECT_EQ(talk_base::ToString<int>(sinfo.packets_lost), value_in_report);
333 EXPECT_TRUE(GetValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000334 report, StatsReport::kStatsValueNameRtt, &value_in_report));
335 EXPECT_EQ(talk_base::ToString<int>(sinfo.rtt_ms), value_in_report);
336 EXPECT_TRUE(GetValue(
337 report, StatsReport::kStatsValueNameRtt, &value_in_report));
338 EXPECT_EQ(talk_base::ToString<int>(sinfo.rtt_ms), value_in_report);
339 EXPECT_TRUE(GetValue(
340 report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
341 EXPECT_EQ(talk_base::ToString<int>(sinfo.jitter_ms), value_in_report);
342 EXPECT_TRUE(GetValue(
343 report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
344 &value_in_report));
345 EXPECT_EQ(talk_base::ToString<float>(sinfo.aec_quality_min), value_in_report);
346 EXPECT_TRUE(GetValue(
347 report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
348 EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_delay_median_ms),
349 value_in_report);
350 EXPECT_TRUE(GetValue(
351 report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
352 EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_delay_std_ms),
353 value_in_report);
354 EXPECT_TRUE(GetValue(
355 report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
356 EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_return_loss),
357 value_in_report);
358 EXPECT_TRUE(GetValue(
359 report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
360 &value_in_report));
361 EXPECT_EQ(talk_base::ToString<int>(sinfo.echo_return_loss_enhancement),
362 value_in_report);
363 EXPECT_TRUE(GetValue(
364 report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report));
365 EXPECT_EQ(talk_base::ToString<int>(sinfo.audio_level), value_in_report);
366 EXPECT_TRUE(GetValue(
367 report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
368 std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
369 EXPECT_EQ(typing_detected, value_in_report);
370}
371
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000372class StatsCollectorTest : public testing::Test {
373 protected:
374 StatsCollectorTest()
375 : media_engine_(new cricket::FakeMediaEngine),
376 channel_manager_(
377 new cricket::ChannelManager(media_engine_,
378 new cricket::FakeDeviceManager(),
379 talk_base::Thread::Current())),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000380 session_(channel_manager_.get()),
381 track_id_(kTrackId) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 // By default, we ignore session GetStats calls.
383 EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false));
384 }
385
wu@webrtc.org97077a32013-10-25 21:18:33 +0000386 // This creates a standard setup with a transport called "trspname"
387 // having one transport channel
388 // and the specified virtual connection name.
389 void InitSessionStats(const std::string vc_name) {
390 const std::string kTransportName("trspname");
391 cricket::TransportStats transport_stats;
392 cricket::TransportChannelStats channel_stats;
393 channel_stats.component = 1;
394 transport_stats.content_name = kTransportName;
395 transport_stats.channel_stats.push_back(channel_stats);
396
397 session_stats_.transport_stats[kTransportName] = transport_stats;
398 session_stats_.proxy_to_transport[vc_name] = kTransportName;
399 }
400
401 // Adds a track with a given SSRC into the stats.
402 void AddVideoTrackStats() {
403 stream_ = webrtc::MediaStream::Create("streamlabel");
404 track_= webrtc::VideoTrack::Create(kTrackId, NULL);
405 stream_->AddTrack(track_);
406 EXPECT_CALL(session_, GetTrackIdBySsrc(kSsrcOfTrack, _))
407 .WillRepeatedly(DoAll(SetArgPointee<1>(track_id_),
408 Return(true)));
409 }
410
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000411 // Adds a local audio track with a given SSRC into the stats.
412 void AddLocalAudioTrackStats() {
413 if (stream_ == NULL)
414 stream_ = webrtc::MediaStream::Create("streamlabel");
415
416 audio_track_ =
417 new talk_base::RefCountedObject<FakeLocalAudioTrack>(kAudioTrackId);
418 stream_->AddTrack(audio_track_);
419 EXPECT_CALL(session_, GetTrackIdBySsrc(kSsrcOfTrack, _))
420 .WillRepeatedly(DoAll(SetArgPointee<1>(kAudioTrackId),
421 Return(true)));
422 }
423
wu@webrtc.org4551b792013-10-09 15:37:36 +0000424 void TestCertificateReports(const talk_base::FakeSSLCertificate& local_cert,
425 const std::vector<std::string>& local_ders,
426 const talk_base::FakeSSLCertificate& remote_cert,
427 const std::vector<std::string>& remote_ders) {
428 webrtc::StatsCollector stats; // Implementation under test.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000429 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000430 stats.set_session(&session_);
431
432 // Fake stats to process.
433 cricket::TransportChannelStats channel_stats;
434 channel_stats.component = 1;
435
436 cricket::TransportStats transport_stats;
437 transport_stats.content_name = "audio";
438 transport_stats.channel_stats.push_back(channel_stats);
439
440 cricket::SessionStats session_stats;
441 session_stats.transport_stats[transport_stats.content_name] =
442 transport_stats;
443
444 // Fake certificates to report.
445 talk_base::FakeSSLIdentity local_identity(local_cert);
446 talk_base::scoped_ptr<talk_base::FakeSSLCertificate> remote_cert_copy(
447 remote_cert.GetReference());
448
449 // Fake transport object.
450 talk_base::scoped_ptr<cricket::FakeTransport> transport(
451 new cricket::FakeTransport(
452 session_.signaling_thread(),
453 session_.worker_thread(),
454 transport_stats.content_name));
455 transport->SetIdentity(&local_identity);
456 cricket::FakeTransportChannel* channel =
457 static_cast<cricket::FakeTransportChannel*>(
458 transport->CreateChannel(channel_stats.component));
459 EXPECT_FALSE(channel == NULL);
460 channel->SetRemoteCertificate(remote_cert_copy.get());
461
462 // Configure MockWebRtcSession
463 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
464 .WillOnce(Return(transport.get()));
465 EXPECT_CALL(session_, GetStats(_))
466 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
467 Return(true)));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000468 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
469 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000470
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000471 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000472
473 stats.GetStats(NULL, &reports);
474
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000475 const StatsReport* channel_report = FindNthReportByType(
476 reports, StatsReport::kStatsReportTypeComponent, 1);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000477 EXPECT_TRUE(channel_report != NULL);
478
479 // Check local certificate chain.
480 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000481 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000482 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000483 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000484 if (local_ders.size() > 0) {
485 EXPECT_NE(kNotFound, local_certificate_id);
486 CheckCertChainReports(reports, local_ders, local_certificate_id);
487 } else {
488 EXPECT_EQ(kNotFound, local_certificate_id);
489 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000490
491 // Check remote certificate chain.
492 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000493 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000494 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000495 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000496 if (remote_ders.size() > 0) {
497 EXPECT_NE(kNotFound, remote_certificate_id);
498 CheckCertChainReports(reports, remote_ders, remote_certificate_id);
499 } else {
500 EXPECT_EQ(kNotFound, remote_certificate_id);
501 }
wu@webrtc.org4551b792013-10-09 15:37:36 +0000502 }
wu@webrtc.org97077a32013-10-25 21:18:33 +0000503
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 cricket::FakeMediaEngine* media_engine_;
505 talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
506 MockWebRtcSession session_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000507 cricket::SessionStats session_stats_;
508 talk_base::scoped_refptr<webrtc::MediaStream> stream_;
509 talk_base::scoped_refptr<webrtc::VideoTrack> track_;
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000510 talk_base::scoped_refptr<FakeLocalAudioTrack> audio_track_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000511 std::string track_id_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000512};
513
514// This test verifies that 64-bit counters are passed successfully.
515TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
516 webrtc::StatsCollector stats; // Implementation under test.
517 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
518 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
519 media_engine_, media_channel, &session_, "", false, NULL);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000520 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000521 cricket::VideoSenderInfo video_sender_info;
522 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000523 // The number of bytes must be larger than 0xFFFFFFFF for this test.
524 const int64 kBytesSent = 12345678901234LL;
525 const std::string kBytesSentString("12345678901234");
526
527 stats.set_session(&session_);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000528 AddVideoTrackStats();
529 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530
531 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000532 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000533 video_sender_info.bytes_sent = kBytesSent;
534 stats_read.senders.push_back(video_sender_info);
535
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000536 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
537 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000538 EXPECT_CALL(*media_channel, GetStats(_, _))
539 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540 Return(true)));
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000541 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542 stats.GetStats(NULL, &reports);
543 std::string result = ExtractSsrcStatsValue(reports, "bytesSent");
544 EXPECT_EQ(kBytesSentString, result);
545}
546
547// Test that BWE information is reported via stats.
548TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
549 webrtc::StatsCollector stats; // Implementation under test.
550 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
551 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
552 media_engine_, media_channel, &session_, "", false, NULL);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000553 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 cricket::VideoSenderInfo video_sender_info;
555 cricket::VideoMediaInfo stats_read;
556 // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
557 // BWE.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000558 const int64 kBytesSent = 12345678901234LL;
559 const std::string kBytesSentString("12345678901234");
560
561 stats.set_session(&session_);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000562 AddVideoTrackStats();
563 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564
565 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000566 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 video_sender_info.bytes_sent = kBytesSent;
568 stats_read.senders.push_back(video_sender_info);
569 cricket::BandwidthEstimationInfo bwe;
570 const int kTargetEncBitrate = 123456;
571 const std::string kTargetEncBitrateString("123456");
572 bwe.target_enc_bitrate = kTargetEncBitrate;
573 stats_read.bw_estimations.push_back(bwe);
574
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000575 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
576 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000577 EXPECT_CALL(*media_channel, GetStats(_, _))
578 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000580
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000581 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000582 stats.GetStats(NULL, &reports);
583 std::string result = ExtractSsrcStatsValue(reports, "bytesSent");
584 EXPECT_EQ(kBytesSentString, result);
585 result = ExtractBweStatsValue(reports, "googTargetEncBitrate");
586 EXPECT_EQ(kTargetEncBitrateString, result);
587}
588
589// This test verifies that an object of type "googSession" always
590// exists in the returned stats.
591TEST_F(StatsCollectorTest, SessionObjectExists) {
592 webrtc::StatsCollector stats; // Implementation under test.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000593 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 stats.set_session(&session_);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000595 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
596 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000597 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000599 const StatsReport* session_report = FindNthReportByType(
600 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000601 EXPECT_FALSE(session_report == NULL);
602}
603
604// This test verifies that only one object of type "googSession" exists
605// in the returned stats.
606TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
607 webrtc::StatsCollector stats; // Implementation under test.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000608 StatsReports reports; // returned values.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000609 stats.set_session(&session_);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000610 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
611 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000612 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
613 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000615 const StatsReport* session_report = FindNthReportByType(
616 reports, StatsReport::kStatsReportTypeSession, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617 EXPECT_FALSE(session_report == NULL);
618 session_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000619 reports, StatsReport::kStatsReportTypeSession, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620 EXPECT_EQ(NULL, session_report);
621}
622
623// This test verifies that the empty track report exists in the returned stats
624// without calling StatsCollector::UpdateStats.
625TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
626 webrtc::StatsCollector stats; // Implementation under test.
627 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
628 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
629 media_engine_, media_channel, &session_, "", false, NULL);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000630 AddVideoTrackStats();
631 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632
633 stats.set_session(&session_);
634
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000635 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636
637 // Verfies the existence of the track report.
638 stats.GetStats(NULL, &reports);
639 EXPECT_EQ((size_t)1, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000640 EXPECT_EQ(std::string(StatsReport::kStatsReportTypeTrack),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641 reports[0].type);
642
643 std::string trackValue =
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000644 ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000646 StatsReport::kStatsValueNameTrackId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000647 EXPECT_EQ(kTrackId, trackValue);
648}
649
650// This test verifies that the empty track report exists in the returned stats
651// when StatsCollector::UpdateStats is called with ssrc stats.
652TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
653 webrtc::StatsCollector stats; // Implementation under test.
654 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
655 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
656 media_engine_, media_channel, &session_, "", false, NULL);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000657 AddVideoTrackStats();
658 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000659
660 stats.set_session(&session_);
661
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000662 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000663
664 // Constructs an ssrc stats update.
665 cricket::VideoSenderInfo video_sender_info;
666 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667 const int64 kBytesSent = 12345678901234LL;
668
669 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000670 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 video_sender_info.bytes_sent = kBytesSent;
672 stats_read.senders.push_back(video_sender_info);
673
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000674 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
675 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000676 EXPECT_CALL(*media_channel, GetStats(_, _))
677 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000679
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000680 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000681 stats.GetStats(NULL, &reports);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000682 // |reports| should contain at least one session report, one track report,
683 // and one ssrc report.
684 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000685 const StatsReport* track_report = FindNthReportByType(
686 reports, StatsReport::kStatsReportTypeTrack, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687 EXPECT_FALSE(track_report == NULL);
688
wu@webrtc.org97077a32013-10-25 21:18:33 +0000689 stats.GetStats(track_, &reports);
690 // |reports| should contain at least one session report, one track report,
691 // and one ssrc report.
692 EXPECT_LE((size_t)3, reports.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693 track_report = FindNthReportByType(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000694 reports, StatsReport::kStatsReportTypeTrack, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 EXPECT_FALSE(track_report == NULL);
696
697 std::string ssrc_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000698 reports, StatsReport::kStatsValueNameSsrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
700
701 std::string track_id = ExtractSsrcStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000702 reports, StatsReport::kStatsValueNameTrackId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 EXPECT_EQ(kTrackId, track_id);
704}
705
706// This test verifies that an SSRC object has the identifier of a Transport
707// stats object, and that this transport stats object exists in stats.
708TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
709 webrtc::StatsCollector stats; // Implementation under test.
710 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
711 // The content_name known by the video channel.
712 const std::string kVcName("vcname");
713 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
714 media_engine_, media_channel, &session_, kVcName, false, NULL);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000715 AddVideoTrackStats();
716 stats.AddStream(stream_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717
718 stats.set_session(&session_);
719
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000720 StatsReports reports;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721
722 // Constructs an ssrc stats update.
723 cricket::VideoSenderInfo video_sender_info;
724 cricket::VideoMediaInfo stats_read;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 const int64 kBytesSent = 12345678901234LL;
726
727 // Construct a stats value to read.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000728 video_sender_info.add_ssrc(1234);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000729 video_sender_info.bytes_sent = kBytesSent;
730 stats_read.senders.push_back(video_sender_info);
731
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000732 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
733 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000734 EXPECT_CALL(*media_channel, GetStats(_, _))
735 .WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000736 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737
wu@webrtc.org97077a32013-10-25 21:18:33 +0000738 InitSessionStats(kVcName);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000739 EXPECT_CALL(session_, GetStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000740 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
741 Return(true)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000742
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000743 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744 stats.GetStats(NULL, &reports);
745 std::string transport_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000746 StatsReport::kStatsReportTypeSsrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000748 StatsReport::kStatsValueNameTransportId);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000749 ASSERT_NE(kNotFound, transport_id);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000750 const StatsReport* transport_report = FindReportById(reports,
751 transport_id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000752 ASSERT_FALSE(transport_report == NULL);
753}
754
wu@webrtc.org97077a32013-10-25 21:18:33 +0000755// This test verifies that a remote stats object will not be created for
756// an outgoing SSRC where remote stats are not returned.
757TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
758 webrtc::StatsCollector stats; // Implementation under test.
759 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
760 // The content_name known by the video channel.
761 const std::string kVcName("vcname");
762 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
763 media_engine_, media_channel, &session_, kVcName, false, NULL);
764 AddVideoTrackStats();
765 stats.AddStream(stream_);
766
767 stats.set_session(&session_);
768
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000769 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
770 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org97077a32013-10-25 21:18:33 +0000771
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000772 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000773 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000774 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000775 const StatsReport* remote_report = FindNthReportByType(reports,
776 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000777 EXPECT_TRUE(remote_report == NULL);
778}
779
780// This test verifies that a remote stats object will be created for
781// an outgoing SSRC where stats are returned.
782TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
783 webrtc::StatsCollector stats; // Implementation under test.
784 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
785 // The content_name known by the video channel.
786 const std::string kVcName("vcname");
787 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
788 media_engine_, media_channel, &session_, kVcName, false, NULL);
789 AddVideoTrackStats();
790 stats.AddStream(stream_);
791
792 stats.set_session(&session_);
793
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000794 StatsReports reports;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000795
796 // Instruct the session to return stats containing the transport channel.
797 InitSessionStats(kVcName);
798 EXPECT_CALL(session_, GetStats(_))
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000799 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
800 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000801
802 // Constructs an ssrc stats update.
803 cricket::VideoMediaInfo stats_read;
804
805 cricket::SsrcReceiverInfo remote_ssrc_stats;
806 remote_ssrc_stats.timestamp = 12345.678;
807 remote_ssrc_stats.ssrc = kSsrcOfTrack;
808 cricket::VideoSenderInfo video_sender_info;
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000809 video_sender_info.add_ssrc(kSsrcOfTrack);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000810 video_sender_info.remote_stats.push_back(remote_ssrc_stats);
811 stats_read.senders.push_back(video_sender_info);
812
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000813 EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
814 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000815 EXPECT_CALL(*media_channel, GetStats(_, _))
816 .WillRepeatedly(DoAll(SetArgPointee<1>(stats_read),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000817 Return(true)));
818
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000819 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000820 stats.GetStats(NULL, &reports);
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000821 const StatsReport* remote_report = FindNthReportByType(reports,
822 StatsReport::kStatsReportTypeRemoteSsrc, 1);
wu@webrtc.org97077a32013-10-25 21:18:33 +0000823 EXPECT_FALSE(remote_report == NULL);
824 EXPECT_NE(0, remote_report->timestamp);
825}
826
wu@webrtc.org4551b792013-10-09 15:37:36 +0000827// This test verifies that all chained certificates are correctly
828// reported
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000829TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000830 // Build local certificate chain.
831 std::vector<std::string> local_ders(5);
832 local_ders[0] = "These";
833 local_ders[1] = "are";
834 local_ders[2] = "some";
835 local_ders[3] = "der";
836 local_ders[4] = "values";
837 talk_base::FakeSSLCertificate local_cert(DersToPems(local_ders));
838
839 // Build remote certificate chain
840 std::vector<std::string> remote_ders(4);
841 remote_ders[0] = "A";
842 remote_ders[1] = "non-";
843 remote_ders[2] = "intersecting";
844 remote_ders[3] = "set";
845 talk_base::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
846
847 TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
848}
849
850// This test verifies that all certificates without chains are correctly
851// reported.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000852TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000853 // Build local certificate.
854 std::string local_der = "This is the local der.";
855 talk_base::FakeSSLCertificate local_cert(DerToPem(local_der));
856
857 // Build remote certificate.
858 std::string remote_der = "This is somebody else's der.";
859 talk_base::FakeSSLCertificate remote_cert(DerToPem(remote_der));
860
861 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
862 remote_cert, std::vector<std::string>(1, remote_der));
863}
864
865// This test verifies that the stats are generated correctly when no
866// transport is present.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000867TEST_F(StatsCollectorTest, NoTransport) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000868 webrtc::StatsCollector stats; // Implementation under test.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000869 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000870 stats.set_session(&session_);
871
872 // Fake stats to process.
873 cricket::TransportChannelStats channel_stats;
874 channel_stats.component = 1;
875
876 cricket::TransportStats transport_stats;
877 transport_stats.content_name = "audio";
878 transport_stats.channel_stats.push_back(channel_stats);
879
880 cricket::SessionStats session_stats;
881 session_stats.transport_stats[transport_stats.content_name] =
882 transport_stats;
883
884 // Configure MockWebRtcSession
885 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
886 .WillOnce(ReturnNull());
887 EXPECT_CALL(session_, GetStats(_))
888 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
889 Return(true)));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000890
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000891 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
892 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000893
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000894 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000895 stats.GetStats(NULL, &reports);
896
897 // Check that the local certificate is absent.
898 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000899 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000900 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000901 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000902 ASSERT_EQ(kNotFound, local_certificate_id);
903
904 // Check that the remote certificate is absent.
905 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000906 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000907 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000908 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000909 ASSERT_EQ(kNotFound, remote_certificate_id);
910}
911
912// This test verifies that the stats are generated correctly when the transport
913// does not have any certificates.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000914TEST_F(StatsCollectorTest, NoCertificates) {
wu@webrtc.org4551b792013-10-09 15:37:36 +0000915 webrtc::StatsCollector stats; // Implementation under test.
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000916 StatsReports reports; // returned values.
wu@webrtc.org4551b792013-10-09 15:37:36 +0000917 stats.set_session(&session_);
918
919 // Fake stats to process.
920 cricket::TransportChannelStats channel_stats;
921 channel_stats.component = 1;
922
923 cricket::TransportStats transport_stats;
924 transport_stats.content_name = "audio";
925 transport_stats.channel_stats.push_back(channel_stats);
926
927 cricket::SessionStats session_stats;
928 session_stats.transport_stats[transport_stats.content_name] =
929 transport_stats;
930
931 // Fake transport object.
932 talk_base::scoped_ptr<cricket::FakeTransport> transport(
933 new cricket::FakeTransport(
934 session_.signaling_thread(),
935 session_.worker_thread(),
936 transport_stats.content_name));
937
938 // Configure MockWebRtcSession
939 EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
940 .WillOnce(Return(transport.get()));
941 EXPECT_CALL(session_, GetStats(_))
942 .WillOnce(DoAll(SetArgPointee<0>(session_stats),
943 Return(true)));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000944 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
945 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000946
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000947 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000948 stats.GetStats(NULL, &reports);
949
950 // Check that the local certificate is absent.
951 std::string local_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000952 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000953 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000954 StatsReport::kStatsValueNameLocalCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000955 ASSERT_EQ(kNotFound, local_certificate_id);
956
957 // Check that the remote certificate is absent.
958 std::string remote_certificate_id = ExtractStatsValue(
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000959 StatsReport::kStatsReportTypeComponent,
wu@webrtc.org4551b792013-10-09 15:37:36 +0000960 reports,
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000961 StatsReport::kStatsValueNameRemoteCertificateId);
wu@webrtc.org4551b792013-10-09 15:37:36 +0000962 ASSERT_EQ(kNotFound, remote_certificate_id);
963}
964
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000965// This test verifies that a remote certificate with an unsupported digest
966// algorithm is correctly ignored.
967TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
968 // Build a local certificate.
969 std::string local_der = "This is the local der.";
970 talk_base::FakeSSLCertificate local_cert(DerToPem(local_der));
971
972 // Build a remote certificate with an unsupported digest algorithm.
973 std::string remote_der = "This is somebody else's der.";
974 talk_base::FakeSSLCertificate remote_cert(DerToPem(remote_der));
975 remote_cert.set_digest_algorithm("foobar");
976
977 TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
978 remote_cert, std::vector<std::string>());
979}
980
981// Verifies the correct optons are passed to the VideoMediaChannel when using
982// verbose output level.
983TEST_F(StatsCollectorTest, StatsOutputLevelVerbose) {
984 webrtc::StatsCollector stats; // Implementation under test.
985 MockVideoMediaChannel* media_channel = new MockVideoMediaChannel;
986 cricket::VideoChannel video_channel(talk_base::Thread::Current(),
987 media_engine_, media_channel, &session_, "", false, NULL);
988 stats.set_session(&session_);
989
henrike@webrtc.org40b3b682014-03-03 18:30:11 +0000990 StatsReports reports; // returned values.
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000991 cricket::VideoMediaInfo stats_read;
992 cricket::BandwidthEstimationInfo bwe;
993 bwe.total_received_propagation_delta_ms = 10;
994 bwe.recent_received_propagation_delta_ms.push_back(100);
995 bwe.recent_received_propagation_delta_ms.push_back(200);
996 bwe.recent_received_packet_group_arrival_time_ms.push_back(1000);
997 bwe.recent_received_packet_group_arrival_time_ms.push_back(2000);
998 stats_read.bw_estimations.push_back(bwe);
999
1000 EXPECT_CALL(session_, video_channel())
1001 .WillRepeatedly(Return(&video_channel));
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001002 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001003
1004 StatsOptions options;
1005 options.include_received_propagation_stats = true;
1006 EXPECT_CALL(*media_channel, GetStats(
1007 Field(&StatsOptions::include_received_propagation_stats, true),
1008 _))
1009 .WillOnce(DoAll(SetArgPointee<1>(stats_read),
1010 Return(true)));
1011
1012 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelDebug);
1013 stats.GetStats(NULL, &reports);
1014 std::string result = ExtractBweStatsValue(
1015 reports, "googReceivedPacketGroupPropagationDeltaSumDebug");
1016 EXPECT_EQ("10", result);
1017 result = ExtractBweStatsValue(
1018 reports, "googReceivedPacketGroupPropagationDeltaDebug");
1019 EXPECT_EQ("[100, 200]", result);
1020 result = ExtractBweStatsValue(
1021 reports, "googReceivedPacketGroupArrivalTimeDebug");
1022 EXPECT_EQ("[1000, 2000]", result);
1023}
1024
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001025// This test verifies that a local stats object can get statistics via
1026// AudioTrackInterface::GetStats() method.
1027TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
1028 webrtc::StatsCollector stats; // Implementation under test.
1029 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1030 // The content_name known by the voice channel.
1031 const std::string kVcName("vcname");
1032 cricket::VoiceChannel voice_channel(talk_base::Thread::Current(),
1033 media_engine_, media_channel, &session_, kVcName, false);
1034 AddLocalAudioTrackStats();
1035 stats.AddStream(stream_);
1036 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1037
1038 stats.set_session(&session_);
1039
1040 // Instruct the session to return stats containing the transport channel.
1041 InitSessionStats(kVcName);
1042 EXPECT_CALL(session_, GetStats(_))
1043 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1044 Return(true)));
1045
1046 cricket::VoiceSenderInfo voice_sender_info;
1047 // Contents won't be modified by the AudioTrackInterface::GetStats().
1048 voice_sender_info.add_ssrc(kSsrcOfTrack);
1049 voice_sender_info.codec_name = "fake_codec";
1050 voice_sender_info.bytes_sent = 100;
1051 voice_sender_info.packets_sent = 101;
1052 voice_sender_info.rtt_ms = 102;
1053 voice_sender_info.fraction_lost = 103;
1054 voice_sender_info.jitter_ms = 104;
1055 voice_sender_info.packets_lost = 105;
1056 voice_sender_info.ext_seqnum = 106;
1057
1058 // Contents will be modified by the AudioTrackInterface::GetStats().
1059 voice_sender_info.audio_level = 107;
1060 voice_sender_info.echo_return_loss = 108;;
1061 voice_sender_info.echo_return_loss_enhancement = 109;
1062 voice_sender_info.echo_delay_median_ms = 110;
1063 voice_sender_info.echo_delay_std_ms = 111;
1064 voice_sender_info.aec_quality_min = 112.0f;
1065 voice_sender_info.typing_noise_detected = false;
1066
1067 // Constructs an ssrc stats update.
1068 cricket::VoiceMediaInfo stats_read;
1069 stats_read.senders.push_back(voice_sender_info);
1070
1071 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1072 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1073 EXPECT_CALL(*media_channel, GetStats(_))
1074 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1075 Return(true)));
1076
1077 StatsReports reports; // returned values.
1078 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1079 stats.GetStats(NULL, &reports);
1080
1081 // Verfy the existence of the track report.
1082 const StatsReport* report = FindNthReportByType(
1083 reports, StatsReport::kStatsReportTypeSsrc, 1);
1084 EXPECT_FALSE(report == NULL);
1085 std::string track_id = ExtractSsrcStatsValue(
1086 reports, StatsReport::kStatsValueNameTrackId);
1087 EXPECT_EQ(kAudioTrackId, track_id);
1088 std::string ssrc_id = ExtractSsrcStatsValue(
1089 reports, StatsReport::kStatsValueNameSsrc);
1090 EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
1091
1092 // Verifies the values in the track report.
1093 audio_track_->GetSignalLevel(&voice_sender_info.audio_level);
1094 webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
1095 audio_track_->GetAudioProcessor()->GetStats(&audio_processor_stats);
1096 voice_sender_info.typing_noise_detected =
1097 audio_processor_stats.typing_noise_detected;
1098 voice_sender_info.echo_return_loss = audio_processor_stats.echo_return_loss;
1099 voice_sender_info.echo_return_loss_enhancement =
1100 audio_processor_stats.echo_return_loss_enhancement;
1101 voice_sender_info.echo_delay_median_ms =
1102 audio_processor_stats.echo_delay_median_ms;
1103 voice_sender_info.aec_quality_min = audio_processor_stats.aec_quality_min;
1104 voice_sender_info.echo_delay_std_ms = audio_processor_stats.echo_delay_std_ms;
1105 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1106
1107 // Verify we get the same result by passing a track to GetStats().
1108 StatsReports track_reports; // returned values.
1109 stats.GetStats(audio_track_.get(), &track_reports);
1110 const StatsReport* track_report = FindNthReportByType(
1111 track_reports, StatsReport::kStatsReportTypeSsrc, 1);
1112 EXPECT_FALSE(track_report == NULL);
1113 track_id = ExtractSsrcStatsValue(track_reports,
1114 StatsReport::kStatsValueNameTrackId);
1115 EXPECT_EQ(kAudioTrackId, track_id);
1116 ssrc_id = ExtractSsrcStatsValue(track_reports,
1117 StatsReport::kStatsValueNameSsrc);
1118 EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
1119 VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
1120}
1121
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +00001122
1123// This test verifies that audio receive streams populate stats reports
1124// correctly.
1125TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) {
1126 webrtc::StatsCollector stats; // Implementation under test.
1127 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1128 // The content_name known by the voice channel.
1129 const std::string kVcName("vcname");
1130 cricket::VoiceChannel voice_channel(talk_base::Thread::Current(),
1131 media_engine_, media_channel, &session_, kVcName, false);
1132 stream_ = webrtc::MediaStream::Create("remoteStreamLabel");
1133 stats.AddStream(stream_);
1134
1135 stats.set_session(&session_);
1136
1137 // Instruct the session to return stats containing the transport channel.
1138 InitSessionStats(kVcName);
1139 EXPECT_CALL(session_, GetStats(_))
1140 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1141 Return(true)));
1142
1143 cricket::VoiceReceiverInfo voice_receiver_info;
1144 voice_receiver_info.add_ssrc(kSsrcOfTrack);
1145 voice_receiver_info.bytes_rcvd = 100;
1146 voice_receiver_info.packets_rcvd = 101;
1147 voice_receiver_info.packets_lost = 102;
1148 voice_receiver_info.fraction_lost = 103;
1149 voice_receiver_info.packets_lost = 104;
1150 voice_receiver_info.ext_seqnum = 105;
1151 voice_receiver_info.jitter_ms = 106;
1152 voice_receiver_info.jitter_buffer_ms = 107;
1153 voice_receiver_info.jitter_buffer_preferred_ms = 108;
1154 voice_receiver_info.delay_estimate_ms = 109;
1155 voice_receiver_info.audio_level = 110;
1156 voice_receiver_info.expand_rate = 111;
1157
1158 // Constructs an ssrc stats update.
1159 cricket::VoiceMediaInfo stats_read;
1160 stats_read.receivers.push_back(voice_receiver_info);
1161
1162 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1163 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1164 EXPECT_CALL(*media_channel, GetStats(_))
1165 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1166 Return(true)));
1167 EXPECT_CALL(session_, GetTrackIdBySsrc(kSsrcOfTrack, _))
1168 .WillRepeatedly(Return(true));
1169
1170 StatsReports reports; // returned values.
1171 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1172 stats.GetStats(NULL, &reports);
1173
1174 // Verify the remote report.
1175 const StatsReport* report = FindNthReportByType(
1176 reports, StatsReport::kStatsReportTypeSsrc, 1);
1177 EXPECT_FALSE(report == NULL);
1178 VerifyVoiceReceiverInfoReport(report, voice_receiver_info);
1179}
1180
1181
henrike@webrtc.org40b3b682014-03-03 18:30:11 +00001182// This test verifies that a local stats object won't update its statistics
1183// after a RemoveLocalAudioTrack() call.
1184TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
1185 webrtc::StatsCollector stats; // Implementation under test.
1186 MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
1187 // The content_name known by the voice channel.
1188 const std::string kVcName("vcname");
1189 cricket::VoiceChannel voice_channel(talk_base::Thread::Current(),
1190 media_engine_, media_channel, &session_, kVcName, false);
1191 AddLocalAudioTrackStats();
1192 stats.AddStream(stream_);
1193 stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1194
1195 stats.set_session(&session_);
1196
1197 // Instruct the session to return stats containing the transport channel.
1198 InitSessionStats(kVcName);
1199 EXPECT_CALL(session_, GetStats(_))
1200 .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
1201 Return(true)));
1202
1203 stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
1204 cricket::VoiceSenderInfo voice_sender_info;
1205 // Contents won't be modified by the AudioTrackInterface::GetStats().
1206 voice_sender_info.add_ssrc(kSsrcOfTrack);
1207 voice_sender_info.codec_name = "fake_codec";
1208 voice_sender_info.bytes_sent = 100;
1209 voice_sender_info.packets_sent = 101;
1210 voice_sender_info.rtt_ms = 102;
1211 voice_sender_info.fraction_lost = 103;
1212 voice_sender_info.jitter_ms = 104;
1213 voice_sender_info.packets_lost = 105;
1214 voice_sender_info.ext_seqnum = 106;
1215
1216 // Contents will be modified by the AudioTrackInterface::GetStats().
1217 voice_sender_info.audio_level = 107;
1218 voice_sender_info.echo_return_loss = 108;;
1219 voice_sender_info.echo_return_loss_enhancement = 109;
1220 voice_sender_info.echo_delay_median_ms = 110;
1221 voice_sender_info.echo_delay_std_ms = 111;
1222 voice_sender_info.aec_quality_min = 112;
1223 voice_sender_info.typing_noise_detected = false;
1224
1225 // Constructs an ssrc stats update.
1226 cricket::VoiceMediaInfo stats_read;
1227 stats_read.senders.push_back(voice_sender_info);
1228
1229 EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
1230 EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
1231 EXPECT_CALL(*media_channel, GetStats(_))
1232 .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
1233 Return(true)));
1234
1235 StatsReports reports; // returned values.
1236 stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
1237 stats.GetStats(NULL, &reports);
1238
1239 // The report will exist since we don't remove them in RemoveStream().
1240 const StatsReport* report = FindNthReportByType(
1241 reports, StatsReport::kStatsReportTypeSsrc, 1);
1242 EXPECT_FALSE(report == NULL);
1243 std::string track_id = ExtractSsrcStatsValue(
1244 reports, StatsReport::kStatsValueNameTrackId);
1245 EXPECT_EQ(kAudioTrackId, track_id);
1246 std::string ssrc_id = ExtractSsrcStatsValue(
1247 reports, StatsReport::kStatsValueNameSsrc);
1248 EXPECT_EQ(talk_base::ToString<uint32>(kSsrcOfTrack), ssrc_id);
1249
1250 // Verifies the values in the track report, no value will be changed by the
1251 // AudioTrackInterface::GetSignalValue() and
1252 // AudioProcessorInterface::AudioProcessorStats::GetStats();
1253 VerifyVoiceSenderInfoReport(report, voice_sender_info);
1254}
1255
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001256} // namespace