Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2014 Google Inc.
      4  *
      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 <algorithm>
     31 
     32 #include "talk/app/webrtc/statscollector.h"
     33 
     34 #include "talk/app/webrtc/peerconnection.h"
     35 #include "talk/app/webrtc/peerconnectionfactory.h"
     36 #include "talk/app/webrtc/mediastream.h"
     37 #include "talk/app/webrtc/mediastreaminterface.h"
     38 #include "talk/app/webrtc/mediastreamtrack.h"
     39 #include "talk/app/webrtc/test/fakedatachannelprovider.h"
     40 #include "talk/app/webrtc/videotrack.h"
     41 #include "talk/media/base/fakemediaengine.h"
     42 #include "talk/session/media/channelmanager.h"
     43 #include "testing/gmock/include/gmock/gmock.h"
     44 #include "testing/gtest/include/gtest/gtest.h"
     45 #include "webrtc/base/base64.h"
     46 #include "webrtc/base/fakesslidentity.h"
     47 #include "webrtc/base/gunit.h"
     48 #include "webrtc/base/network.h"
     49 #include "webrtc/p2p/base/faketransportcontroller.h"
     50 
     51 using rtc::scoped_ptr;
     52 using testing::_;
     53 using testing::DoAll;
     54 using testing::Field;
     55 using testing::Return;
     56 using testing::ReturnNull;
     57 using testing::ReturnRef;
     58 using testing::SetArgPointee;
     59 using webrtc::PeerConnectionInterface;
     60 using webrtc::StatsReport;
     61 using webrtc::StatsReports;
     62 
     63 namespace {
     64 // This value comes from openssl/tls1.h
     65 const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
     66 }  // namespace
     67 
     68 namespace cricket {
     69 
     70 class ChannelManager;
     71 
     72 }  // namespace cricket
     73 
     74 namespace webrtc {
     75 
     76 // Error return values
     77 const char kNotFound[] = "NOT FOUND";
     78 
     79 // Constant names for track identification.
     80 const char kLocalTrackId[] = "local_track_id";
     81 const char kRemoteTrackId[] = "remote_track_id";
     82 const uint32_t kSsrcOfTrack = 1234;
     83 
     84 class MockWebRtcSession : public webrtc::WebRtcSession {
     85  public:
     86   explicit MockWebRtcSession(webrtc::MediaControllerInterface* media_controller)
     87       : WebRtcSession(media_controller,
     88                       rtc::Thread::Current(),
     89                       rtc::Thread::Current(),
     90                       nullptr) {}
     91   MOCK_METHOD0(voice_channel, cricket::VoiceChannel*());
     92   MOCK_METHOD0(video_channel, cricket::VideoChannel*());
     93   // Libjingle uses "local" for a outgoing track, and "remote" for a incoming
     94   // track.
     95   MOCK_METHOD2(GetLocalTrackIdBySsrc, bool(uint32_t, std::string*));
     96   MOCK_METHOD2(GetRemoteTrackIdBySsrc, bool(uint32_t, std::string*));
     97   MOCK_METHOD1(GetTransportStats, bool(SessionStats*));
     98   MOCK_METHOD2(GetLocalCertificate,
     99                bool(const std::string& transport_name,
    100                     rtc::scoped_refptr<rtc::RTCCertificate>* certificate));
    101   MOCK_METHOD2(GetRemoteSSLCertificate,
    102                bool(const std::string& transport_name,
    103                     rtc::SSLCertificate** cert));
    104 };
    105 
    106 // The factory isn't really used; it just satisfies the base PeerConnection.
    107 class FakePeerConnectionFactory
    108     : public rtc::RefCountedObject<PeerConnectionFactory> {};
    109 
    110 class MockPeerConnection
    111     : public rtc::RefCountedObject<webrtc::PeerConnection> {
    112  public:
    113   MockPeerConnection()
    114       : rtc::RefCountedObject<webrtc::PeerConnection>(
    115             new FakePeerConnectionFactory()) {}
    116   MOCK_METHOD0(session, WebRtcSession*());
    117   MOCK_CONST_METHOD0(sctp_data_channels,
    118                      const std::vector<rtc::scoped_refptr<DataChannel>>&());
    119 };
    120 
    121 class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
    122  public:
    123   MockVideoMediaChannel() :
    124       cricket::FakeVideoMediaChannel(NULL, cricket::VideoOptions()) {}
    125   MOCK_METHOD1(GetStats, bool(cricket::VideoMediaInfo*));
    126 };
    127 
    128 class MockVoiceMediaChannel : public cricket::FakeVoiceMediaChannel {
    129  public:
    130   MockVoiceMediaChannel() :
    131       cricket::FakeVoiceMediaChannel(NULL, cricket::AudioOptions()) {}
    132   MOCK_METHOD1(GetStats, bool(cricket::VoiceMediaInfo*));
    133 };
    134 
    135 class FakeAudioProcessor : public webrtc::AudioProcessorInterface {
    136  public:
    137   FakeAudioProcessor() {}
    138   ~FakeAudioProcessor() {}
    139 
    140  private:
    141   void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override {
    142     stats->typing_noise_detected = true;
    143     stats->echo_return_loss = 2;
    144     stats->echo_return_loss_enhancement = 3;
    145     stats->echo_delay_median_ms = 4;
    146     stats->aec_quality_min = 5.1f;
    147     stats->echo_delay_std_ms = 6;
    148   }
    149 };
    150 
    151 class FakeAudioTrack
    152     : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> {
    153  public:
    154   explicit FakeAudioTrack(const std::string& id)
    155       : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id),
    156         processor_(new rtc::RefCountedObject<FakeAudioProcessor>()) {}
    157   std::string kind() const override { return "audio"; }
    158   webrtc::AudioSourceInterface* GetSource() const override { return NULL; }
    159   void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
    160   void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
    161   bool GetSignalLevel(int* level) override {
    162     *level = 1;
    163     return true;
    164   }
    165   rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor()
    166       override {
    167     return processor_;
    168   }
    169 
    170  private:
    171   rtc::scoped_refptr<FakeAudioProcessor> processor_;
    172 };
    173 
    174 bool GetValue(const StatsReport* report,
    175               StatsReport::StatsValueName name,
    176               std::string* value) {
    177   const StatsReport::Value* v = report->FindValue(name);
    178   if (!v)
    179     return false;
    180   *value = v->ToString();
    181   return true;
    182 }
    183 
    184 std::string ExtractStatsValue(const StatsReport::StatsType& type,
    185                               const StatsReports& reports,
    186                               StatsReport::StatsValueName name) {
    187   for (const auto* r : reports) {
    188     std::string ret;
    189     if (r->type() == type && GetValue(r, name, &ret))
    190       return ret;
    191   }
    192 
    193   return kNotFound;
    194 }
    195 
    196 StatsReport::Id TypedIdFromIdString(StatsReport::StatsType type,
    197                                     const std::string& value) {
    198   EXPECT_FALSE(value.empty());
    199   StatsReport::Id id;
    200   if (value.empty())
    201     return id;
    202 
    203   // This has assumptions about how the ID is constructed.  As is, this is
    204   // OK since this is for testing purposes only, but if we ever need this
    205   // in production, we should add a generic method that does this.
    206   size_t index = value.find('_');
    207   EXPECT_NE(index, std::string::npos);
    208   if (index == std::string::npos || index == (value.length() - 1))
    209     return id;
    210 
    211   id = StatsReport::NewTypedId(type, value.substr(index + 1));
    212   EXPECT_EQ(id->ToString(), value);
    213   return id;
    214 }
    215 
    216 StatsReport::Id IdFromCertIdString(const std::string& cert_id) {
    217   return TypedIdFromIdString(StatsReport::kStatsReportTypeCertificate, cert_id);
    218 }
    219 
    220 // Finds the |n|-th report of type |type| in |reports|.
    221 // |n| starts from 1 for finding the first report.
    222 const StatsReport* FindNthReportByType(
    223     const StatsReports& reports, const StatsReport::StatsType& type, int n) {
    224   for (size_t i = 0; i < reports.size(); ++i) {
    225     if (reports[i]->type() == type) {
    226       n--;
    227       if (n == 0)
    228         return reports[i];
    229     }
    230   }
    231   return nullptr;
    232 }
    233 
    234 const StatsReport* FindReportById(const StatsReports& reports,
    235                                   const StatsReport::Id& id) {
    236   for (const auto* r : reports) {
    237     if (r->id()->Equals(id))
    238       return r;
    239   }
    240   return nullptr;
    241 }
    242 
    243 std::string ExtractSsrcStatsValue(StatsReports reports,
    244                                   StatsReport::StatsValueName name) {
    245   return ExtractStatsValue(StatsReport::kStatsReportTypeSsrc, reports, name);
    246 }
    247 
    248 std::string ExtractBweStatsValue(StatsReports reports,
    249                                  StatsReport::StatsValueName name) {
    250   return ExtractStatsValue(
    251       StatsReport::kStatsReportTypeBwe, reports, name);
    252 }
    253 
    254 std::string DerToPem(const std::string& der) {
    255   return rtc::SSLIdentity::DerToPem(
    256         rtc::kPemTypeCertificate,
    257         reinterpret_cast<const unsigned char*>(der.c_str()),
    258         der.length());
    259 }
    260 
    261 std::vector<std::string> DersToPems(
    262     const std::vector<std::string>& ders) {
    263   std::vector<std::string> pems(ders.size());
    264   std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
    265   return pems;
    266 }
    267 
    268 void CheckCertChainReports(const StatsReports& reports,
    269                            const std::vector<std::string>& ders,
    270                            const StatsReport::Id& start_id) {
    271   StatsReport::Id cert_id;
    272   const StatsReport::Id* certificate_id = &start_id;
    273   size_t i = 0;
    274   while (true) {
    275     const StatsReport* report = FindReportById(reports, *certificate_id);
    276     ASSERT_TRUE(report != NULL);
    277 
    278     std::string der_base64;
    279     EXPECT_TRUE(GetValue(
    280         report, StatsReport::kStatsValueNameDer, &der_base64));
    281     std::string der = rtc::Base64::Decode(der_base64, rtc::Base64::DO_STRICT);
    282     EXPECT_EQ(ders[i], der);
    283 
    284     std::string fingerprint_algorithm;
    285     EXPECT_TRUE(GetValue(
    286         report,
    287         StatsReport::kStatsValueNameFingerprintAlgorithm,
    288         &fingerprint_algorithm));
    289     // The digest algorithm for a FakeSSLCertificate is always SHA-1.
    290     std::string sha_1_str = rtc::DIGEST_SHA_1;
    291     EXPECT_EQ(sha_1_str, fingerprint_algorithm);
    292 
    293     std::string fingerprint;
    294     EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameFingerprint,
    295                          &fingerprint));
    296     EXPECT_FALSE(fingerprint.empty());
    297 
    298     ++i;
    299     std::string issuer_id;
    300     if (!GetValue(report, StatsReport::kStatsValueNameIssuerId,
    301                   &issuer_id)) {
    302       break;
    303     }
    304 
    305     cert_id = IdFromCertIdString(issuer_id);
    306     certificate_id = &cert_id;
    307   }
    308   EXPECT_EQ(ders.size(), i);
    309 }
    310 
    311 void VerifyVoiceReceiverInfoReport(
    312     const StatsReport* report,
    313     const cricket::VoiceReceiverInfo& info) {
    314   std::string value_in_report;
    315   EXPECT_TRUE(GetValue(
    316       report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report));
    317   EXPECT_EQ(rtc::ToString<int>(info.audio_level), value_in_report);
    318   EXPECT_TRUE(GetValue(
    319       report, StatsReport::kStatsValueNameBytesReceived, &value_in_report));
    320   EXPECT_EQ(rtc::ToString<int64_t>(info.bytes_rcvd), value_in_report);
    321   EXPECT_TRUE(GetValue(
    322       report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
    323   EXPECT_EQ(rtc::ToString<int>(info.jitter_ms), value_in_report);
    324   EXPECT_TRUE(GetValue(
    325       report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report));
    326   EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_ms), value_in_report);
    327   EXPECT_TRUE(GetValue(
    328       report, StatsReport::kStatsValueNamePreferredJitterBufferMs,
    329       &value_in_report));
    330   EXPECT_EQ(rtc::ToString<int>(info.jitter_buffer_preferred_ms),
    331       value_in_report);
    332   EXPECT_TRUE(GetValue(
    333       report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report));
    334   EXPECT_EQ(rtc::ToString<int>(info.delay_estimate_ms), value_in_report);
    335   EXPECT_TRUE(GetValue(
    336       report, StatsReport::kStatsValueNameExpandRate, &value_in_report));
    337   EXPECT_EQ(rtc::ToString<float>(info.expand_rate), value_in_report);
    338   EXPECT_TRUE(GetValue(
    339       report, StatsReport::kStatsValueNameSpeechExpandRate, &value_in_report));
    340   EXPECT_EQ(rtc::ToString<float>(info.speech_expand_rate), value_in_report);
    341   EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAccelerateRate,
    342                        &value_in_report));
    343   EXPECT_EQ(rtc::ToString<float>(info.accelerate_rate), value_in_report);
    344   EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePreemptiveExpandRate,
    345                        &value_in_report));
    346   EXPECT_EQ(rtc::ToString<float>(info.preemptive_expand_rate), value_in_report);
    347   EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameSecondaryDecodedRate,
    348                        &value_in_report));
    349   EXPECT_EQ(rtc::ToString<float>(info.secondary_decoded_rate), value_in_report);
    350   EXPECT_TRUE(GetValue(
    351       report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report));
    352   EXPECT_EQ(rtc::ToString<int>(info.packets_rcvd), value_in_report);
    353   EXPECT_TRUE(GetValue(
    354       report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report));
    355   EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_silence_generator),
    356       value_in_report);
    357   EXPECT_TRUE(GetValue(
    358       report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report));
    359   EXPECT_EQ(rtc::ToString<int>(info.decoding_calls_to_neteq),
    360       value_in_report);
    361   EXPECT_TRUE(GetValue(
    362       report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report));
    363   EXPECT_EQ(rtc::ToString<int>(info.decoding_normal), value_in_report);
    364   EXPECT_TRUE(GetValue(
    365       report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report));
    366   EXPECT_EQ(rtc::ToString<int>(info.decoding_plc), value_in_report);
    367   EXPECT_TRUE(GetValue(
    368       report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report));
    369   EXPECT_EQ(rtc::ToString<int>(info.decoding_cng), value_in_report);
    370   EXPECT_TRUE(GetValue(
    371       report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report));
    372   EXPECT_EQ(rtc::ToString<int>(info.decoding_plc_cng), value_in_report);
    373   EXPECT_TRUE(GetValue(
    374       report, StatsReport::kStatsValueNameCodecName, &value_in_report));
    375 }
    376 
    377 
    378 void VerifyVoiceSenderInfoReport(const StatsReport* report,
    379                                  const cricket::VoiceSenderInfo& sinfo) {
    380   std::string value_in_report;
    381   EXPECT_TRUE(GetValue(
    382       report, StatsReport::kStatsValueNameCodecName, &value_in_report));
    383   EXPECT_EQ(sinfo.codec_name, value_in_report);
    384   EXPECT_TRUE(GetValue(
    385       report, StatsReport::kStatsValueNameBytesSent, &value_in_report));
    386   EXPECT_EQ(rtc::ToString<int64_t>(sinfo.bytes_sent), value_in_report);
    387   EXPECT_TRUE(GetValue(
    388       report, StatsReport::kStatsValueNamePacketsSent, &value_in_report));
    389   EXPECT_EQ(rtc::ToString<int>(sinfo.packets_sent), value_in_report);
    390   EXPECT_TRUE(GetValue(
    391       report, StatsReport::kStatsValueNamePacketsLost, &value_in_report));
    392   EXPECT_EQ(rtc::ToString<int>(sinfo.packets_lost), value_in_report);
    393   EXPECT_TRUE(GetValue(
    394       report, StatsReport::kStatsValueNameRtt, &value_in_report));
    395   EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
    396   EXPECT_TRUE(GetValue(
    397       report, StatsReport::kStatsValueNameRtt, &value_in_report));
    398   EXPECT_EQ(rtc::ToString<int>(sinfo.rtt_ms), value_in_report);
    399   EXPECT_TRUE(GetValue(
    400       report, StatsReport::kStatsValueNameJitterReceived, &value_in_report));
    401   EXPECT_EQ(rtc::ToString<int>(sinfo.jitter_ms), value_in_report);
    402   EXPECT_TRUE(GetValue(
    403       report, StatsReport::kStatsValueNameEchoCancellationQualityMin,
    404       &value_in_report));
    405   EXPECT_EQ(rtc::ToString<float>(sinfo.aec_quality_min), value_in_report);
    406   EXPECT_TRUE(GetValue(
    407       report, StatsReport::kStatsValueNameEchoDelayMedian, &value_in_report));
    408   EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_median_ms),
    409             value_in_report);
    410   EXPECT_TRUE(GetValue(
    411       report, StatsReport::kStatsValueNameEchoDelayStdDev, &value_in_report));
    412   EXPECT_EQ(rtc::ToString<int>(sinfo.echo_delay_std_ms),
    413             value_in_report);
    414   EXPECT_TRUE(GetValue(
    415       report, StatsReport::kStatsValueNameEchoReturnLoss, &value_in_report));
    416   EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss),
    417             value_in_report);
    418   EXPECT_TRUE(GetValue(
    419       report, StatsReport::kStatsValueNameEchoReturnLossEnhancement,
    420       &value_in_report));
    421   EXPECT_EQ(rtc::ToString<int>(sinfo.echo_return_loss_enhancement),
    422             value_in_report);
    423   EXPECT_TRUE(GetValue(
    424       report, StatsReport::kStatsValueNameAudioInputLevel, &value_in_report));
    425   EXPECT_EQ(rtc::ToString<int>(sinfo.audio_level), value_in_report);
    426   EXPECT_TRUE(GetValue(
    427       report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report));
    428   std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false";
    429   EXPECT_EQ(typing_detected, value_in_report);
    430 }
    431 
    432 // Helper methods to avoid duplication of code.
    433 void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) {
    434   voice_sender_info->add_ssrc(kSsrcOfTrack);
    435   voice_sender_info->codec_name = "fake_codec";
    436   voice_sender_info->bytes_sent = 100;
    437   voice_sender_info->packets_sent = 101;
    438   voice_sender_info->rtt_ms = 102;
    439   voice_sender_info->fraction_lost = 103;
    440   voice_sender_info->jitter_ms = 104;
    441   voice_sender_info->packets_lost = 105;
    442   voice_sender_info->ext_seqnum = 106;
    443   voice_sender_info->audio_level = 107;
    444   voice_sender_info->echo_return_loss = 108;
    445   voice_sender_info->echo_return_loss_enhancement = 109;
    446   voice_sender_info->echo_delay_median_ms = 110;
    447   voice_sender_info->echo_delay_std_ms = 111;
    448   voice_sender_info->aec_quality_min = 112.0f;
    449   voice_sender_info->typing_noise_detected = false;
    450 }
    451 
    452 void UpdateVoiceSenderInfoFromAudioTrack(
    453     FakeAudioTrack* audio_track, cricket::VoiceSenderInfo* voice_sender_info) {
    454   audio_track->GetSignalLevel(&voice_sender_info->audio_level);
    455   webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats;
    456   audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats);
    457   voice_sender_info->typing_noise_detected =
    458       audio_processor_stats.typing_noise_detected;
    459   voice_sender_info->echo_return_loss = audio_processor_stats.echo_return_loss;
    460   voice_sender_info->echo_return_loss_enhancement =
    461       audio_processor_stats.echo_return_loss_enhancement;
    462   voice_sender_info->echo_delay_median_ms =
    463       audio_processor_stats.echo_delay_median_ms;
    464   voice_sender_info->aec_quality_min = audio_processor_stats.aec_quality_min;
    465   voice_sender_info->echo_delay_std_ms =
    466       audio_processor_stats.echo_delay_std_ms;
    467 }
    468 
    469 void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) {
    470   voice_receiver_info->add_ssrc(kSsrcOfTrack);
    471   voice_receiver_info->bytes_rcvd = 110;
    472   voice_receiver_info->packets_rcvd = 111;
    473   voice_receiver_info->packets_lost = 112;
    474   voice_receiver_info->fraction_lost = 113;
    475   voice_receiver_info->packets_lost = 114;
    476   voice_receiver_info->ext_seqnum = 115;
    477   voice_receiver_info->jitter_ms = 116;
    478   voice_receiver_info->jitter_buffer_ms = 117;
    479   voice_receiver_info->jitter_buffer_preferred_ms = 118;
    480   voice_receiver_info->delay_estimate_ms = 119;
    481   voice_receiver_info->audio_level = 120;
    482   voice_receiver_info->expand_rate = 121;
    483   voice_receiver_info->speech_expand_rate = 122;
    484   voice_receiver_info->secondary_decoded_rate = 123;
    485   voice_receiver_info->accelerate_rate = 124;
    486   voice_receiver_info->preemptive_expand_rate = 125;
    487 }
    488 
    489 class StatsCollectorForTest : public webrtc::StatsCollector {
    490  public:
    491   explicit StatsCollectorForTest(PeerConnection* pc)
    492       : StatsCollector(pc), time_now_(19477) {}
    493 
    494   double GetTimeNow() override {
    495     return time_now_;
    496   }
    497 
    498  private:
    499   double time_now_;
    500 };
    501 
    502 class StatsCollectorTest : public testing::Test {
    503  protected:
    504   StatsCollectorTest()
    505       : media_engine_(new cricket::FakeMediaEngine()),
    506         channel_manager_(
    507             new cricket::ChannelManager(media_engine_, rtc::Thread::Current())),
    508         media_controller_(
    509             webrtc::MediaControllerInterface::Create(rtc::Thread::Current(),
    510                                                      channel_manager_.get())),
    511         session_(media_controller_.get()) {
    512     // By default, we ignore session GetStats calls.
    513     EXPECT_CALL(session_, GetTransportStats(_)).WillRepeatedly(Return(false));
    514     // Add default returns for mock classes.
    515     EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
    516     EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
    517     EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
    518     EXPECT_CALL(pc_, sctp_data_channels())
    519         .WillRepeatedly(ReturnRef(data_channels_));
    520   }
    521 
    522   ~StatsCollectorTest() {}
    523 
    524   // This creates a standard setup with a transport called "trspname"
    525   // having one transport channel
    526   // and the specified virtual connection name.
    527   void InitSessionStats(const std::string& vc_name) {
    528     const std::string kTransportName("trspname");
    529     cricket::TransportStats transport_stats;
    530     cricket::TransportChannelStats channel_stats;
    531     channel_stats.component = 1;
    532     transport_stats.transport_name = kTransportName;
    533     transport_stats.channel_stats.push_back(channel_stats);
    534 
    535     session_stats_.transport_stats[kTransportName] = transport_stats;
    536     session_stats_.proxy_to_transport[vc_name] = kTransportName;
    537   }
    538 
    539   // Adds a outgoing video track with a given SSRC into the stats.
    540   void AddOutgoingVideoTrackStats() {
    541     stream_ = webrtc::MediaStream::Create("streamlabel");
    542     track_= webrtc::VideoTrack::Create(kLocalTrackId, NULL);
    543     stream_->AddTrack(track_);
    544     EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
    545         .WillRepeatedly(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
    546   }
    547 
    548   // Adds a incoming video track with a given SSRC into the stats.
    549   void AddIncomingVideoTrackStats() {
    550     stream_ = webrtc::MediaStream::Create("streamlabel");
    551     track_= webrtc::VideoTrack::Create(kRemoteTrackId, NULL);
    552     stream_->AddTrack(track_);
    553     EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
    554         .WillRepeatedly(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
    555     }
    556 
    557   // Adds a outgoing audio track with a given SSRC into the stats.
    558   void AddOutgoingAudioTrackStats() {
    559     if (stream_ == NULL)
    560       stream_ = webrtc::MediaStream::Create("streamlabel");
    561 
    562     audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
    563         kLocalTrackId);
    564     stream_->AddTrack(audio_track_);
    565     EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
    566         .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true)));
    567   }
    568 
    569   // Adds a incoming audio track with a given SSRC into the stats.
    570   void AddIncomingAudioTrackStats() {
    571     if (stream_ == NULL)
    572       stream_ = webrtc::MediaStream::Create("streamlabel");
    573 
    574     audio_track_ = new rtc::RefCountedObject<FakeAudioTrack>(
    575         kRemoteTrackId);
    576     stream_->AddTrack(audio_track_);
    577     EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
    578         .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
    579   }
    580 
    581   void AddDataChannel(cricket::DataChannelType type,
    582                       const std::string& label,
    583                       int id) {
    584     InternalDataChannelInit config;
    585     config.id = id;
    586 
    587     data_channels_.push_back(DataChannel::Create(
    588         &data_channel_provider_, cricket::DCT_SCTP, label, config));
    589   }
    590 
    591   StatsReport* AddCandidateReport(StatsCollector* collector,
    592                                   const cricket::Candidate& candidate,
    593                                   bool local) {
    594     return collector->AddCandidateReport(candidate, local);
    595   }
    596 
    597   void SetupAndVerifyAudioTrackStats(
    598       FakeAudioTrack* audio_track,
    599       webrtc::MediaStream* stream,
    600       webrtc::StatsCollector* stats,
    601       cricket::VoiceChannel* voice_channel,
    602       const std::string& vc_name,
    603       MockVoiceMediaChannel* media_channel,
    604       cricket::VoiceSenderInfo* voice_sender_info,
    605       cricket::VoiceReceiverInfo* voice_receiver_info,
    606       cricket::VoiceMediaInfo* stats_read,
    607       StatsReports* reports) {
    608     // A track can't have both sender report and recv report at the same time
    609     // for now, this might change in the future though.
    610     ASSERT((voice_sender_info == NULL) ^ (voice_receiver_info == NULL));
    611 
    612     // Instruct the session to return stats containing the transport channel.
    613     InitSessionStats(vc_name);
    614     EXPECT_CALL(session_, GetTransportStats(_))
    615         .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
    616                               Return(true)));
    617 
    618     // Constructs an ssrc stats update.
    619     if (voice_sender_info)
    620       stats_read->senders.push_back(*voice_sender_info);
    621     if (voice_receiver_info)
    622       stats_read->receivers.push_back(*voice_receiver_info);
    623 
    624     EXPECT_CALL(session_, voice_channel()).WillRepeatedly(
    625         Return(voice_channel));
    626     EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
    627     EXPECT_CALL(*media_channel, GetStats(_))
    628         .WillOnce(DoAll(SetArgPointee<0>(*stats_read), Return(true)));
    629 
    630     stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    631     stats->ClearUpdateStatsCacheForTest();
    632     stats->GetStats(NULL, reports);
    633 
    634     // Verify the existence of the track report.
    635     const StatsReport* report = FindNthReportByType(
    636         *reports, StatsReport::kStatsReportTypeSsrc, 1);
    637     EXPECT_FALSE(report == NULL);
    638     EXPECT_EQ(stats->GetTimeNow(), report->timestamp());
    639     std::string track_id = ExtractSsrcStatsValue(
    640         *reports, StatsReport::kStatsValueNameTrackId);
    641     EXPECT_EQ(audio_track->id(), track_id);
    642     std::string ssrc_id = ExtractSsrcStatsValue(
    643         *reports, StatsReport::kStatsValueNameSsrc);
    644     EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
    645 
    646     // Verifies the values in the track report.
    647     if (voice_sender_info) {
    648       UpdateVoiceSenderInfoFromAudioTrack(audio_track, voice_sender_info);
    649       VerifyVoiceSenderInfoReport(report, *voice_sender_info);
    650     }
    651     if (voice_receiver_info) {
    652       VerifyVoiceReceiverInfoReport(report, *voice_receiver_info);
    653     }
    654 
    655     // Verify we get the same result by passing a track to GetStats().
    656     StatsReports track_reports;  // returned values.
    657     stats->GetStats(audio_track, &track_reports);
    658     const StatsReport* track_report = FindNthReportByType(
    659         track_reports, StatsReport::kStatsReportTypeSsrc, 1);
    660     EXPECT_TRUE(track_report);
    661     EXPECT_EQ(stats->GetTimeNow(), track_report->timestamp());
    662     track_id = ExtractSsrcStatsValue(track_reports,
    663                                      StatsReport::kStatsValueNameTrackId);
    664     EXPECT_EQ(audio_track->id(), track_id);
    665     ssrc_id = ExtractSsrcStatsValue(track_reports,
    666                                     StatsReport::kStatsValueNameSsrc);
    667     EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
    668     if (voice_sender_info)
    669       VerifyVoiceSenderInfoReport(track_report, *voice_sender_info);
    670     if (voice_receiver_info)
    671     VerifyVoiceReceiverInfoReport(track_report, *voice_receiver_info);
    672   }
    673 
    674   void TestCertificateReports(const rtc::FakeSSLCertificate& local_cert,
    675                               const std::vector<std::string>& local_ders,
    676                               const rtc::FakeSSLCertificate& remote_cert,
    677                               const std::vector<std::string>& remote_ders) {
    678     StatsCollectorForTest stats(&pc_);
    679 
    680     StatsReports reports;  // returned values.
    681 
    682     // Fake stats to process.
    683     cricket::TransportChannelStats channel_stats;
    684     channel_stats.component = 1;
    685     channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
    686     channel_stats.ssl_cipher_suite = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
    687 
    688     cricket::TransportStats transport_stats;
    689     transport_stats.transport_name = "audio";
    690     transport_stats.channel_stats.push_back(channel_stats);
    691 
    692     SessionStats session_stats;
    693     session_stats.transport_stats[transport_stats.transport_name] =
    694         transport_stats;
    695 
    696     // Fake certificate to report
    697     rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
    698         rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::FakeSSLIdentity>(
    699             new rtc::FakeSSLIdentity(local_cert))));
    700 
    701     // Configure MockWebRtcSession
    702     EXPECT_CALL(session_,
    703                 GetLocalCertificate(transport_stats.transport_name, _))
    704         .WillOnce(DoAll(SetArgPointee<1>(local_certificate), Return(true)));
    705     EXPECT_CALL(session_,
    706                 GetRemoteSSLCertificate(transport_stats.transport_name, _))
    707         .WillOnce(
    708             DoAll(SetArgPointee<1>(remote_cert.GetReference()), Return(true)));
    709     EXPECT_CALL(session_, GetTransportStats(_))
    710       .WillOnce(DoAll(SetArgPointee<0>(session_stats),
    711                       Return(true)));
    712 
    713     stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    714 
    715     stats.GetStats(NULL, &reports);
    716 
    717     const StatsReport* channel_report = FindNthReportByType(
    718         reports, StatsReport::kStatsReportTypeComponent, 1);
    719     EXPECT_TRUE(channel_report != NULL);
    720 
    721     // Check local certificate chain.
    722     std::string local_certificate_id = ExtractStatsValue(
    723         StatsReport::kStatsReportTypeComponent,
    724         reports,
    725         StatsReport::kStatsValueNameLocalCertificateId);
    726     if (local_ders.size() > 0) {
    727       EXPECT_NE(kNotFound, local_certificate_id);
    728       StatsReport::Id id(IdFromCertIdString(local_certificate_id));
    729       CheckCertChainReports(reports, local_ders, id);
    730     } else {
    731       EXPECT_EQ(kNotFound, local_certificate_id);
    732     }
    733 
    734     // Check remote certificate chain.
    735     std::string remote_certificate_id = ExtractStatsValue(
    736         StatsReport::kStatsReportTypeComponent,
    737         reports,
    738         StatsReport::kStatsValueNameRemoteCertificateId);
    739     if (remote_ders.size() > 0) {
    740       EXPECT_NE(kNotFound, remote_certificate_id);
    741       StatsReport::Id id(IdFromCertIdString(remote_certificate_id));
    742       CheckCertChainReports(reports, remote_ders, id);
    743     } else {
    744       EXPECT_EQ(kNotFound, remote_certificate_id);
    745     }
    746 
    747     // Check negotiated ciphers.
    748     std::string dtls_cipher_suite =
    749         ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
    750                           StatsReport::kStatsValueNameDtlsCipher);
    751     EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
    752                   TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
    753               dtls_cipher_suite);
    754     std::string srtp_crypto_suite =
    755         ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
    756                           StatsReport::kStatsValueNameSrtpCipher);
    757     EXPECT_EQ(rtc::SrtpCryptoSuiteToName(rtc::SRTP_AES128_CM_SHA1_80),
    758               srtp_crypto_suite);
    759   }
    760 
    761   cricket::FakeMediaEngine* media_engine_;
    762   rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
    763   rtc::scoped_ptr<webrtc::MediaControllerInterface> media_controller_;
    764   MockWebRtcSession session_;
    765   MockPeerConnection pc_;
    766   FakeDataChannelProvider data_channel_provider_;
    767   SessionStats session_stats_;
    768   rtc::scoped_refptr<webrtc::MediaStream> stream_;
    769   rtc::scoped_refptr<webrtc::VideoTrack> track_;
    770   rtc::scoped_refptr<FakeAudioTrack> audio_track_;
    771   std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
    772 };
    773 
    774 // Verify that ExtractDataInfo populates reports.
    775 TEST_F(StatsCollectorTest, ExtractDataInfo) {
    776   const std::string label = "hacks";
    777   const int id = 31337;
    778   const std::string state = DataChannelInterface::DataStateString(
    779       DataChannelInterface::DataState::kConnecting);
    780 
    781   AddDataChannel(cricket::DCT_SCTP, label, id);
    782   StatsCollectorForTest stats(&pc_);
    783 
    784   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    785 
    786   StatsReports reports;
    787   stats.GetStats(NULL, &reports);
    788 
    789   const StatsReport* report =
    790       FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1);
    791 
    792   StatsReport::Id reportId = StatsReport::NewTypedIntId(
    793       StatsReport::kStatsReportTypeDataChannel, id);
    794 
    795   EXPECT_TRUE(reportId->Equals(report->id()));
    796 
    797   EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
    798   EXPECT_EQ(label, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
    799                                      reports,
    800                                      StatsReport::kStatsValueNameLabel));
    801   EXPECT_EQ(rtc::ToString<int64_t>(id),
    802             ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel, reports,
    803                               StatsReport::kStatsValueNameDataChannelId));
    804   EXPECT_EQ(state, ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
    805                                      reports,
    806                                      StatsReport::kStatsValueNameState));
    807   EXPECT_EQ("", ExtractStatsValue(StatsReport::kStatsReportTypeDataChannel,
    808                                   reports,
    809                                   StatsReport::kStatsValueNameProtocol));
    810 }
    811 
    812 // This test verifies that 64-bit counters are passed successfully.
    813 TEST_F(StatsCollectorTest, BytesCounterHandles64Bits) {
    814   StatsCollectorForTest stats(&pc_);
    815 
    816   EXPECT_CALL(session_, GetLocalCertificate(_, _))
    817       .WillRepeatedly(Return(false));
    818   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
    819       .WillRepeatedly(Return(false));
    820 
    821   const char kVideoChannelName[] = "video";
    822 
    823   InitSessionStats(kVideoChannelName);
    824   EXPECT_CALL(session_, GetTransportStats(_))
    825       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
    826                             Return(true)));
    827 
    828   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
    829   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
    830                                       nullptr, kVideoChannelName, false);
    831   StatsReports reports;  // returned values.
    832   cricket::VideoSenderInfo video_sender_info;
    833   cricket::VideoMediaInfo stats_read;
    834   // The number of bytes must be larger than 0xFFFFFFFF for this test.
    835   const int64_t kBytesSent = 12345678901234LL;
    836   const std::string kBytesSentString("12345678901234");
    837 
    838   AddOutgoingVideoTrackStats();
    839   stats.AddStream(stream_);
    840 
    841   // Construct a stats value to read.
    842   video_sender_info.add_ssrc(1234);
    843   video_sender_info.bytes_sent = kBytesSent;
    844   stats_read.senders.push_back(video_sender_info);
    845 
    846   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
    847   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
    848   EXPECT_CALL(*media_channel, GetStats(_))
    849       .WillOnce(DoAll(SetArgPointee<0>(stats_read),
    850                       Return(true)));
    851   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    852   stats.GetStats(NULL, &reports);
    853   std::string result = ExtractSsrcStatsValue(reports,
    854       StatsReport::kStatsValueNameBytesSent);
    855   EXPECT_EQ(kBytesSentString, result);
    856 }
    857 
    858 // Test that BWE information is reported via stats.
    859 TEST_F(StatsCollectorTest, BandwidthEstimationInfoIsReported) {
    860   StatsCollectorForTest stats(&pc_);
    861 
    862   EXPECT_CALL(session_, GetLocalCertificate(_, _))
    863       .WillRepeatedly(Return(false));
    864   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
    865       .WillRepeatedly(Return(false));
    866 
    867   const char kVideoChannelName[] = "video";
    868 
    869   InitSessionStats(kVideoChannelName);
    870   EXPECT_CALL(session_, GetTransportStats(_))
    871       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
    872                             Return(true)));
    873 
    874   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
    875   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
    876                                       nullptr, kVideoChannelName, false);
    877 
    878   StatsReports reports;  // returned values.
    879   cricket::VideoSenderInfo video_sender_info;
    880   cricket::VideoMediaInfo stats_read;
    881   // Set up an SSRC just to test that we get both kinds of stats back: SSRC and
    882   // BWE.
    883   const int64_t kBytesSent = 12345678901234LL;
    884   const std::string kBytesSentString("12345678901234");
    885 
    886   AddOutgoingVideoTrackStats();
    887   stats.AddStream(stream_);
    888 
    889   // Construct a stats value to read.
    890   video_sender_info.add_ssrc(1234);
    891   video_sender_info.bytes_sent = kBytesSent;
    892   stats_read.senders.push_back(video_sender_info);
    893   cricket::BandwidthEstimationInfo bwe;
    894   const int kTargetEncBitrate = 123456;
    895   const std::string kTargetEncBitrateString("123456");
    896   bwe.target_enc_bitrate = kTargetEncBitrate;
    897   stats_read.bw_estimations.push_back(bwe);
    898 
    899   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
    900   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
    901   EXPECT_CALL(*media_channel, GetStats(_))
    902       .WillOnce(DoAll(SetArgPointee<0>(stats_read), Return(true)));
    903 
    904   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    905   stats.GetStats(NULL, &reports);
    906   std::string result = ExtractSsrcStatsValue(reports,
    907       StatsReport::kStatsValueNameBytesSent);
    908   EXPECT_EQ(kBytesSentString, result);
    909   result = ExtractBweStatsValue(reports,
    910       StatsReport::kStatsValueNameTargetEncBitrate);
    911   EXPECT_EQ(kTargetEncBitrateString, result);
    912 }
    913 
    914 // This test verifies that an object of type "googSession" always
    915 // exists in the returned stats.
    916 TEST_F(StatsCollectorTest, SessionObjectExists) {
    917   StatsCollectorForTest stats(&pc_);
    918 
    919   StatsReports reports;  // returned values.
    920   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    921   stats.GetStats(NULL, &reports);
    922   const StatsReport* session_report = FindNthReportByType(
    923       reports, StatsReport::kStatsReportTypeSession, 1);
    924   EXPECT_FALSE(session_report == NULL);
    925 }
    926 
    927 // This test verifies that only one object of type "googSession" exists
    928 // in the returned stats.
    929 TEST_F(StatsCollectorTest, OnlyOneSessionObjectExists) {
    930   StatsCollectorForTest stats(&pc_);
    931 
    932   StatsReports reports;  // returned values.
    933   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    934   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
    935   stats.GetStats(NULL, &reports);
    936   const StatsReport* session_report = FindNthReportByType(
    937       reports, StatsReport::kStatsReportTypeSession, 1);
    938   EXPECT_FALSE(session_report == NULL);
    939   session_report = FindNthReportByType(
    940       reports, StatsReport::kStatsReportTypeSession, 2);
    941   EXPECT_EQ(NULL, session_report);
    942 }
    943 
    944 // This test verifies that the empty track report exists in the returned stats
    945 // without calling StatsCollector::UpdateStats.
    946 TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) {
    947   StatsCollectorForTest stats(&pc_);
    948 
    949   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
    950   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
    951                                       nullptr, "video", false);
    952   AddOutgoingVideoTrackStats();
    953   stats.AddStream(stream_);
    954 
    955   // Verfies the existence of the track report.
    956   StatsReports reports;
    957   stats.GetStats(NULL, &reports);
    958   EXPECT_EQ((size_t)1, reports.size());
    959   EXPECT_EQ(StatsReport::kStatsReportTypeTrack, reports[0]->type());
    960   EXPECT_EQ(0, reports[0]->timestamp());
    961 
    962   std::string trackValue =
    963       ExtractStatsValue(StatsReport::kStatsReportTypeTrack,
    964                         reports,
    965                         StatsReport::kStatsValueNameTrackId);
    966   EXPECT_EQ(kLocalTrackId, trackValue);
    967 }
    968 
    969 // This test verifies that the empty track report exists in the returned stats
    970 // when StatsCollector::UpdateStats is called with ssrc stats.
    971 TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) {
    972   StatsCollectorForTest stats(&pc_);
    973 
    974   EXPECT_CALL(session_, GetLocalCertificate(_, _))
    975       .WillRepeatedly(Return(false));
    976   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
    977       .WillRepeatedly(Return(false));
    978 
    979   const char kVideoChannelName[] = "video";
    980   InitSessionStats(kVideoChannelName);
    981   EXPECT_CALL(session_, GetTransportStats(_))
    982       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
    983                             Return(true)));
    984 
    985   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
    986   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
    987                                       nullptr, kVideoChannelName, false);
    988   AddOutgoingVideoTrackStats();
    989   stats.AddStream(stream_);
    990 
    991   // Constructs an ssrc stats update.
    992   cricket::VideoSenderInfo video_sender_info;
    993   cricket::VideoMediaInfo stats_read;
    994   const int64_t kBytesSent = 12345678901234LL;
    995 
    996   // Construct a stats value to read.
    997   video_sender_info.add_ssrc(1234);
    998   video_sender_info.bytes_sent = kBytesSent;
    999   stats_read.senders.push_back(video_sender_info);
   1000 
   1001   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
   1002   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
   1003   EXPECT_CALL(*media_channel, GetStats(_))
   1004     .WillOnce(DoAll(SetArgPointee<0>(stats_read),
   1005                     Return(true)));
   1006 
   1007   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1008   StatsReports reports;
   1009   stats.GetStats(NULL, &reports);
   1010   // |reports| should contain at least one session report, one track report,
   1011   // and one ssrc report.
   1012   EXPECT_LE((size_t)3, reports.size());
   1013   const StatsReport* track_report = FindNthReportByType(
   1014       reports, StatsReport::kStatsReportTypeTrack, 1);
   1015   EXPECT_TRUE(track_report);
   1016 
   1017   // Get report for the specific |track|.
   1018   reports.clear();
   1019   stats.GetStats(track_, &reports);
   1020   // |reports| should contain at least one session report, one track report,
   1021   // and one ssrc report.
   1022   EXPECT_LE((size_t)3, reports.size());
   1023   track_report = FindNthReportByType(
   1024       reports, StatsReport::kStatsReportTypeTrack, 1);
   1025   EXPECT_TRUE(track_report);
   1026   EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
   1027 
   1028   std::string ssrc_id = ExtractSsrcStatsValue(
   1029       reports, StatsReport::kStatsValueNameSsrc);
   1030   EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
   1031 
   1032   std::string track_id = ExtractSsrcStatsValue(
   1033       reports, StatsReport::kStatsValueNameTrackId);
   1034   EXPECT_EQ(kLocalTrackId, track_id);
   1035 }
   1036 
   1037 // This test verifies that an SSRC object has the identifier of a Transport
   1038 // stats object, and that this transport stats object exists in stats.
   1039 TEST_F(StatsCollectorTest, TransportObjectLinkedFromSsrcObject) {
   1040   StatsCollectorForTest stats(&pc_);
   1041 
   1042   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1043       .WillRepeatedly(Return(false));
   1044   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1045       .WillRepeatedly(Return(false));
   1046 
   1047   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   1048   // The transport_name known by the video channel.
   1049   const std::string kVcName("vcname");
   1050   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
   1051                                       nullptr, kVcName, false);
   1052   AddOutgoingVideoTrackStats();
   1053   stats.AddStream(stream_);
   1054 
   1055   // Constructs an ssrc stats update.
   1056   cricket::VideoSenderInfo video_sender_info;
   1057   cricket::VideoMediaInfo stats_read;
   1058   const int64_t kBytesSent = 12345678901234LL;
   1059 
   1060   // Construct a stats value to read.
   1061   video_sender_info.add_ssrc(1234);
   1062   video_sender_info.bytes_sent = kBytesSent;
   1063   stats_read.senders.push_back(video_sender_info);
   1064 
   1065   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
   1066   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
   1067   EXPECT_CALL(*media_channel, GetStats(_))
   1068     .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
   1069                           Return(true)));
   1070 
   1071   InitSessionStats(kVcName);
   1072   EXPECT_CALL(session_, GetTransportStats(_))
   1073       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
   1074                             Return(true)));
   1075 
   1076   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1077   StatsReports reports;
   1078   stats.GetStats(NULL, &reports);
   1079   std::string transport_id = ExtractStatsValue(
   1080       StatsReport::kStatsReportTypeSsrc,
   1081       reports,
   1082       StatsReport::kStatsValueNameTransportId);
   1083   ASSERT_NE(kNotFound, transport_id);
   1084   // Transport id component ID will always be 1.
   1085   // This has assumptions about how the ID is constructed.  As is, this is
   1086   // OK since this is for testing purposes only, but if we ever need this
   1087   // in production, we should add a generic method that does this.
   1088   size_t index = transport_id.find('-');
   1089   ASSERT_NE(std::string::npos, index);
   1090   std::string content = transport_id.substr(index + 1);
   1091   index = content.rfind('-');
   1092   ASSERT_NE(std::string::npos, index);
   1093   content = content.substr(0, index);
   1094   StatsReport::Id id(StatsReport::NewComponentId(content, 1));
   1095   ASSERT_EQ(transport_id, id->ToString());
   1096   const StatsReport* transport_report = FindReportById(reports, id);
   1097   ASSERT_FALSE(transport_report == NULL);
   1098 }
   1099 
   1100 // This test verifies that a remote stats object will not be created for
   1101 // an outgoing SSRC where remote stats are not returned.
   1102 TEST_F(StatsCollectorTest, RemoteSsrcInfoIsAbsent) {
   1103   StatsCollectorForTest stats(&pc_);
   1104 
   1105   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   1106   // The transport_name known by the video channel.
   1107   const std::string kVcName("vcname");
   1108   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
   1109                                       nullptr, kVcName, false);
   1110   AddOutgoingVideoTrackStats();
   1111   stats.AddStream(stream_);
   1112 
   1113   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1114   StatsReports reports;
   1115   stats.GetStats(NULL, &reports);
   1116   const StatsReport* remote_report = FindNthReportByType(reports,
   1117       StatsReport::kStatsReportTypeRemoteSsrc, 1);
   1118   EXPECT_TRUE(remote_report == NULL);
   1119 }
   1120 
   1121 // This test verifies that a remote stats object will be created for
   1122 // an outgoing SSRC where stats are returned.
   1123 TEST_F(StatsCollectorTest, RemoteSsrcInfoIsPresent) {
   1124   StatsCollectorForTest stats(&pc_);
   1125 
   1126   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1127       .WillRepeatedly(Return(false));
   1128   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1129       .WillRepeatedly(Return(false));
   1130 
   1131   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   1132   // The transport_name known by the video channel.
   1133   const std::string kVcName("vcname");
   1134   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
   1135                                       nullptr, kVcName, false);
   1136   AddOutgoingVideoTrackStats();
   1137   stats.AddStream(stream_);
   1138 
   1139   // Instruct the session to return stats containing the transport channel.
   1140   InitSessionStats(kVcName);
   1141   EXPECT_CALL(session_, GetTransportStats(_))
   1142       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
   1143                             Return(true)));
   1144 
   1145   // Constructs an ssrc stats update.
   1146   cricket::VideoMediaInfo stats_read;
   1147 
   1148   cricket::SsrcReceiverInfo remote_ssrc_stats;
   1149   remote_ssrc_stats.timestamp = 12345.678;
   1150   remote_ssrc_stats.ssrc = kSsrcOfTrack;
   1151   cricket::VideoSenderInfo video_sender_info;
   1152   video_sender_info.add_ssrc(kSsrcOfTrack);
   1153   video_sender_info.remote_stats.push_back(remote_ssrc_stats);
   1154   stats_read.senders.push_back(video_sender_info);
   1155 
   1156   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
   1157   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
   1158   EXPECT_CALL(*media_channel, GetStats(_))
   1159     .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
   1160                           Return(true)));
   1161 
   1162   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1163   StatsReports reports;
   1164   stats.GetStats(NULL, &reports);
   1165 
   1166   const StatsReport* remote_report = FindNthReportByType(reports,
   1167       StatsReport::kStatsReportTypeRemoteSsrc, 1);
   1168   EXPECT_FALSE(remote_report == NULL);
   1169   EXPECT_EQ(12345.678, remote_report->timestamp());
   1170 }
   1171 
   1172 // This test verifies that the empty track report exists in the returned stats
   1173 // when StatsCollector::UpdateStats is called with ssrc stats.
   1174 TEST_F(StatsCollectorTest, ReportsFromRemoteTrack) {
   1175   StatsCollectorForTest stats(&pc_);
   1176 
   1177   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1178       .WillRepeatedly(Return(false));
   1179   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1180       .WillRepeatedly(Return(false));
   1181 
   1182   const char kVideoChannelName[] = "video";
   1183   InitSessionStats(kVideoChannelName);
   1184   EXPECT_CALL(session_, GetTransportStats(_))
   1185       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
   1186                             Return(true)));
   1187 
   1188   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   1189   cricket::VideoChannel video_channel(rtc::Thread::Current(), media_channel,
   1190                                       nullptr, kVideoChannelName, false);
   1191   AddIncomingVideoTrackStats();
   1192   stats.AddStream(stream_);
   1193 
   1194   // Constructs an ssrc stats update.
   1195   cricket::VideoReceiverInfo video_receiver_info;
   1196   cricket::VideoMediaInfo stats_read;
   1197   const int64_t kNumOfPacketsConcealed = 54321;
   1198 
   1199   // Construct a stats value to read.
   1200   video_receiver_info.add_ssrc(1234);
   1201   video_receiver_info.packets_concealed = kNumOfPacketsConcealed;
   1202   stats_read.receivers.push_back(video_receiver_info);
   1203 
   1204   EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel));
   1205   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(ReturnNull());
   1206   EXPECT_CALL(*media_channel, GetStats(_))
   1207       .WillOnce(DoAll(SetArgPointee<0>(stats_read),
   1208                       Return(true)));
   1209 
   1210   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1211   StatsReports reports;
   1212   stats.GetStats(NULL, &reports);
   1213   // |reports| should contain at least one session report, one track report,
   1214   // and one ssrc report.
   1215   EXPECT_LE(static_cast<size_t>(3), reports.size());
   1216   const StatsReport* track_report = FindNthReportByType(
   1217       reports, StatsReport::kStatsReportTypeTrack, 1);
   1218   EXPECT_TRUE(track_report);
   1219   EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
   1220 
   1221   std::string ssrc_id = ExtractSsrcStatsValue(
   1222       reports, StatsReport::kStatsValueNameSsrc);
   1223   EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
   1224 
   1225   std::string track_id = ExtractSsrcStatsValue(
   1226       reports, StatsReport::kStatsValueNameTrackId);
   1227   EXPECT_EQ(kRemoteTrackId, track_id);
   1228 }
   1229 
   1230 // This test verifies the Ice Candidate report should contain the correct
   1231 // information from local/remote candidates.
   1232 TEST_F(StatsCollectorTest, IceCandidateReport) {
   1233   StatsCollectorForTest stats(&pc_);
   1234 
   1235   StatsReports reports;                     // returned values.
   1236 
   1237   const int local_port = 2000;
   1238   const char local_ip[] = "192.168.0.1";
   1239   const int remote_port = 2001;
   1240   const char remote_ip[] = "192.168.0.2";
   1241 
   1242   rtc::SocketAddress local_address(local_ip, local_port);
   1243   rtc::SocketAddress remote_address(remote_ip, remote_port);
   1244   rtc::AdapterType network_type = rtc::ADAPTER_TYPE_ETHERNET;
   1245   uint32_t priority = 1000;
   1246 
   1247   cricket::Candidate c;
   1248   ASSERT(c.id().length() > 0);
   1249   c.set_type(cricket::LOCAL_PORT_TYPE);
   1250   c.set_protocol(cricket::UDP_PROTOCOL_NAME);
   1251   c.set_address(local_address);
   1252   c.set_priority(priority);
   1253   c.set_network_type(network_type);
   1254   std::string report_id = AddCandidateReport(&stats, c, true)->id()->ToString();
   1255   EXPECT_EQ("Cand-" + c.id(), report_id);
   1256 
   1257   c = cricket::Candidate();
   1258   ASSERT(c.id().length() > 0);
   1259   c.set_type(cricket::PRFLX_PORT_TYPE);
   1260   c.set_protocol(cricket::UDP_PROTOCOL_NAME);
   1261   c.set_address(remote_address);
   1262   c.set_priority(priority);
   1263   c.set_network_type(network_type);
   1264   report_id = AddCandidateReport(&stats, c, false)->id()->ToString();
   1265   EXPECT_EQ("Cand-" + c.id(), report_id);
   1266 
   1267   stats.GetStats(NULL, &reports);
   1268 
   1269   // Verify the local candidate report is populated correctly.
   1270   EXPECT_EQ(
   1271       local_ip,
   1272       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1273                         StatsReport::kStatsValueNameCandidateIPAddress));
   1274   EXPECT_EQ(
   1275       rtc::ToString<int>(local_port),
   1276       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1277                         StatsReport::kStatsValueNameCandidatePortNumber));
   1278   EXPECT_EQ(
   1279       cricket::UDP_PROTOCOL_NAME,
   1280       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1281                         StatsReport::kStatsValueNameCandidateTransportType));
   1282   EXPECT_EQ(
   1283       rtc::ToString<int>(priority),
   1284       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1285                         StatsReport::kStatsValueNameCandidatePriority));
   1286   EXPECT_EQ(
   1287       IceCandidateTypeToStatsType(cricket::LOCAL_PORT_TYPE),
   1288       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1289                         StatsReport::kStatsValueNameCandidateType));
   1290   EXPECT_EQ(
   1291       AdapterTypeToStatsType(network_type),
   1292       ExtractStatsValue(StatsReport::kStatsReportTypeIceLocalCandidate, reports,
   1293                         StatsReport::kStatsValueNameCandidateNetworkType));
   1294 
   1295   // Verify the remote candidate report is populated correctly.
   1296   EXPECT_EQ(remote_ip,
   1297             ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
   1298                               reports,
   1299                               StatsReport::kStatsValueNameCandidateIPAddress));
   1300   EXPECT_EQ(rtc::ToString<int>(remote_port),
   1301             ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
   1302                               reports,
   1303                               StatsReport::kStatsValueNameCandidatePortNumber));
   1304   EXPECT_EQ(cricket::UDP_PROTOCOL_NAME,
   1305             ExtractStatsValue(
   1306                 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
   1307                 StatsReport::kStatsValueNameCandidateTransportType));
   1308   EXPECT_EQ(rtc::ToString<int>(priority),
   1309             ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
   1310                               reports,
   1311                               StatsReport::kStatsValueNameCandidatePriority));
   1312   EXPECT_EQ(
   1313       IceCandidateTypeToStatsType(cricket::PRFLX_PORT_TYPE),
   1314       ExtractStatsValue(StatsReport::kStatsReportTypeIceRemoteCandidate,
   1315                         reports, StatsReport::kStatsValueNameCandidateType));
   1316   EXPECT_EQ(kNotFound,
   1317             ExtractStatsValue(
   1318                 StatsReport::kStatsReportTypeIceRemoteCandidate, reports,
   1319                 StatsReport::kStatsValueNameCandidateNetworkType));
   1320 }
   1321 
   1322 // This test verifies that all chained certificates are correctly
   1323 // reported
   1324 TEST_F(StatsCollectorTest, ChainedCertificateReportsCreated) {
   1325   // Build local certificate chain.
   1326   std::vector<std::string> local_ders(5);
   1327   local_ders[0] = "These";
   1328   local_ders[1] = "are";
   1329   local_ders[2] = "some";
   1330   local_ders[3] = "der";
   1331   local_ders[4] = "values";
   1332   rtc::FakeSSLCertificate local_cert(DersToPems(local_ders));
   1333 
   1334   // Build remote certificate chain
   1335   std::vector<std::string> remote_ders(4);
   1336   remote_ders[0] = "A";
   1337   remote_ders[1] = "non-";
   1338   remote_ders[2] = "intersecting";
   1339   remote_ders[3] = "set";
   1340   rtc::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
   1341 
   1342   TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
   1343 }
   1344 
   1345 // This test verifies that all certificates without chains are correctly
   1346 // reported.
   1347 TEST_F(StatsCollectorTest, ChainlessCertificateReportsCreated) {
   1348   // Build local certificate.
   1349   std::string local_der = "This is the local der.";
   1350   rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
   1351 
   1352   // Build remote certificate.
   1353   std::string remote_der = "This is somebody else's der.";
   1354   rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
   1355 
   1356   TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
   1357                          remote_cert, std::vector<std::string>(1, remote_der));
   1358 }
   1359 
   1360 // This test verifies that the stats are generated correctly when no
   1361 // transport is present.
   1362 TEST_F(StatsCollectorTest, NoTransport) {
   1363   StatsCollectorForTest stats(&pc_);
   1364 
   1365   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1366       .WillRepeatedly(Return(false));
   1367   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1368       .WillRepeatedly(Return(false));
   1369 
   1370   StatsReports reports;  // returned values.
   1371 
   1372   // Fake stats to process.
   1373   cricket::TransportChannelStats channel_stats;
   1374   channel_stats.component = 1;
   1375 
   1376   cricket::TransportStats transport_stats;
   1377   transport_stats.transport_name = "audio";
   1378   transport_stats.channel_stats.push_back(channel_stats);
   1379 
   1380   SessionStats session_stats;
   1381   session_stats.transport_stats[transport_stats.transport_name] =
   1382       transport_stats;
   1383 
   1384   // Configure MockWebRtcSession
   1385   EXPECT_CALL(session_, GetTransportStats(_))
   1386     .WillOnce(DoAll(SetArgPointee<0>(session_stats),
   1387                     Return(true)));
   1388 
   1389   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1390   stats.GetStats(NULL, &reports);
   1391 
   1392   // Check that the local certificate is absent.
   1393   std::string local_certificate_id = ExtractStatsValue(
   1394       StatsReport::kStatsReportTypeComponent,
   1395       reports,
   1396       StatsReport::kStatsValueNameLocalCertificateId);
   1397   ASSERT_EQ(kNotFound, local_certificate_id);
   1398 
   1399   // Check that the remote certificate is absent.
   1400   std::string remote_certificate_id = ExtractStatsValue(
   1401       StatsReport::kStatsReportTypeComponent,
   1402       reports,
   1403       StatsReport::kStatsValueNameRemoteCertificateId);
   1404   ASSERT_EQ(kNotFound, remote_certificate_id);
   1405 
   1406   // Check that the negotiated ciphers are absent.
   1407   std::string dtls_cipher_suite =
   1408       ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
   1409                         StatsReport::kStatsValueNameDtlsCipher);
   1410   ASSERT_EQ(kNotFound, dtls_cipher_suite);
   1411   std::string srtp_crypto_suite =
   1412       ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
   1413                         StatsReport::kStatsValueNameSrtpCipher);
   1414   ASSERT_EQ(kNotFound, srtp_crypto_suite);
   1415 }
   1416 
   1417 // This test verifies that the stats are generated correctly when the transport
   1418 // does not have any certificates.
   1419 TEST_F(StatsCollectorTest, NoCertificates) {
   1420   StatsCollectorForTest stats(&pc_);
   1421 
   1422   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1423       .WillRepeatedly(Return(false));
   1424   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1425       .WillRepeatedly(Return(false));
   1426 
   1427   StatsReports reports;  // returned values.
   1428 
   1429   // Fake stats to process.
   1430   cricket::TransportChannelStats channel_stats;
   1431   channel_stats.component = 1;
   1432 
   1433   cricket::TransportStats transport_stats;
   1434   transport_stats.transport_name = "audio";
   1435   transport_stats.channel_stats.push_back(channel_stats);
   1436 
   1437   SessionStats session_stats;
   1438   session_stats.transport_stats[transport_stats.transport_name] =
   1439       transport_stats;
   1440 
   1441   // Fake transport object.
   1442   rtc::scoped_ptr<cricket::FakeTransport> transport(
   1443       new cricket::FakeTransport(transport_stats.transport_name));
   1444 
   1445   // Configure MockWebRtcSession
   1446   EXPECT_CALL(session_, GetTransportStats(_))
   1447     .WillOnce(DoAll(SetArgPointee<0>(session_stats),
   1448                     Return(true)));
   1449   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1450   stats.GetStats(NULL, &reports);
   1451 
   1452   // Check that the local certificate is absent.
   1453   std::string local_certificate_id = ExtractStatsValue(
   1454       StatsReport::kStatsReportTypeComponent,
   1455       reports,
   1456       StatsReport::kStatsValueNameLocalCertificateId);
   1457   ASSERT_EQ(kNotFound, local_certificate_id);
   1458 
   1459   // Check that the remote certificate is absent.
   1460   std::string remote_certificate_id = ExtractStatsValue(
   1461       StatsReport::kStatsReportTypeComponent,
   1462       reports,
   1463       StatsReport::kStatsValueNameRemoteCertificateId);
   1464   ASSERT_EQ(kNotFound, remote_certificate_id);
   1465 }
   1466 
   1467 // This test verifies that a remote certificate with an unsupported digest
   1468 // algorithm is correctly ignored.
   1469 TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) {
   1470   // Build a local certificate.
   1471   std::string local_der = "This is the local der.";
   1472   rtc::FakeSSLCertificate local_cert(DerToPem(local_der));
   1473 
   1474   // Build a remote certificate with an unsupported digest algorithm.
   1475   std::string remote_der = "This is somebody else's der.";
   1476   rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
   1477   remote_cert.set_digest_algorithm("foobar");
   1478 
   1479   TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
   1480                          remote_cert, std::vector<std::string>());
   1481 }
   1482 
   1483 // This test verifies that a local stats object can get statistics via
   1484 // AudioTrackInterface::GetStats() method.
   1485 TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) {
   1486   StatsCollectorForTest stats(&pc_);
   1487 
   1488   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1489       .WillRepeatedly(Return(false));
   1490   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1491       .WillRepeatedly(Return(false));
   1492 
   1493   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   1494   // The transport_name known by the voice channel.
   1495   const std::string kVcName("vcname");
   1496   cricket::VoiceChannel voice_channel(rtc::Thread::Current(), media_engine_,
   1497                                       media_channel, nullptr, kVcName, false);
   1498   AddOutgoingAudioTrackStats();
   1499   stats.AddStream(stream_);
   1500   stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
   1501 
   1502   cricket::VoiceSenderInfo voice_sender_info;
   1503   InitVoiceSenderInfo(&voice_sender_info);
   1504 
   1505   cricket::VoiceMediaInfo stats_read;
   1506   StatsReports reports;  // returned values.
   1507   SetupAndVerifyAudioTrackStats(
   1508       audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
   1509       media_channel, &voice_sender_info, NULL, &stats_read, &reports);
   1510 
   1511   // Verify that there is no remote report for the local audio track because
   1512   // we did not set it up.
   1513   const StatsReport* remote_report = FindNthReportByType(reports,
   1514       StatsReport::kStatsReportTypeRemoteSsrc, 1);
   1515   EXPECT_TRUE(remote_report == NULL);
   1516 }
   1517 
   1518 // This test verifies that audio receive streams populate stats reports
   1519 // correctly.
   1520 TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) {
   1521   StatsCollectorForTest stats(&pc_);
   1522 
   1523   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1524       .WillRepeatedly(Return(false));
   1525   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1526       .WillRepeatedly(Return(false));
   1527 
   1528   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   1529   // The transport_name known by the voice channel.
   1530   const std::string kVcName("vcname");
   1531   cricket::VoiceChannel voice_channel(rtc::Thread::Current(), media_engine_,
   1532                                       media_channel, nullptr, kVcName, false);
   1533   AddIncomingAudioTrackStats();
   1534   stats.AddStream(stream_);
   1535 
   1536   cricket::VoiceReceiverInfo voice_receiver_info;
   1537   InitVoiceReceiverInfo(&voice_receiver_info);
   1538   voice_receiver_info.codec_name = "fake_codec";
   1539 
   1540   cricket::VoiceMediaInfo stats_read;
   1541   StatsReports reports;  // returned values.
   1542   SetupAndVerifyAudioTrackStats(
   1543       audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
   1544       media_channel, NULL, &voice_receiver_info, &stats_read, &reports);
   1545 }
   1546 
   1547 // This test verifies that a local stats object won't update its statistics
   1548 // after a RemoveLocalAudioTrack() call.
   1549 TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) {
   1550   StatsCollectorForTest stats(&pc_);
   1551 
   1552   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1553       .WillRepeatedly(Return(false));
   1554   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1555       .WillRepeatedly(Return(false));
   1556 
   1557   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   1558   // The transport_name known by the voice channel.
   1559   const std::string kVcName("vcname");
   1560   cricket::VoiceChannel voice_channel(rtc::Thread::Current(), media_engine_,
   1561                                       media_channel, nullptr, kVcName, false);
   1562   AddOutgoingAudioTrackStats();
   1563   stats.AddStream(stream_);
   1564   stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
   1565 
   1566   // Instruct the session to return stats containing the transport channel.
   1567   InitSessionStats(kVcName);
   1568   EXPECT_CALL(session_, GetTransportStats(_))
   1569       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
   1570                             Return(true)));
   1571 
   1572   stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
   1573   cricket::VoiceSenderInfo voice_sender_info;
   1574   InitVoiceSenderInfo(&voice_sender_info);
   1575 
   1576   // Constructs an ssrc stats update.
   1577   cricket::VoiceMediaInfo stats_read;
   1578   stats_read.senders.push_back(voice_sender_info);
   1579 
   1580   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
   1581   EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
   1582   EXPECT_CALL(*media_channel, GetStats(_))
   1583       .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
   1584                             Return(true)));
   1585 
   1586   StatsReports reports;  // returned values.
   1587   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1588   stats.GetStats(NULL, &reports);
   1589 
   1590   // The report will exist since we don't remove them in RemoveStream().
   1591   const StatsReport* report = FindNthReportByType(
   1592       reports, StatsReport::kStatsReportTypeSsrc, 1);
   1593   EXPECT_FALSE(report == NULL);
   1594   EXPECT_EQ(stats.GetTimeNow(), report->timestamp());
   1595   std::string track_id = ExtractSsrcStatsValue(
   1596       reports, StatsReport::kStatsValueNameTrackId);
   1597   EXPECT_EQ(kLocalTrackId, track_id);
   1598   std::string ssrc_id = ExtractSsrcStatsValue(
   1599       reports, StatsReport::kStatsValueNameSsrc);
   1600   EXPECT_EQ(rtc::ToString<uint32_t>(kSsrcOfTrack), ssrc_id);
   1601 
   1602   // Verifies the values in the track report, no value will be changed by the
   1603   // AudioTrackInterface::GetSignalValue() and
   1604   // AudioProcessorInterface::AudioProcessorStats::GetStats();
   1605   VerifyVoiceSenderInfoReport(report, voice_sender_info);
   1606 }
   1607 
   1608 // This test verifies that when ongoing and incoming audio tracks are using
   1609 // the same ssrc, they populate stats reports correctly.
   1610 TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) {
   1611   StatsCollectorForTest stats(&pc_);
   1612 
   1613   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1614       .WillRepeatedly(Return(false));
   1615   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1616       .WillRepeatedly(Return(false));
   1617 
   1618   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   1619   // The transport_name known by the voice channel.
   1620   const std::string kVcName("vcname");
   1621   cricket::VoiceChannel voice_channel(rtc::Thread::Current(), media_engine_,
   1622                                       media_channel, nullptr, kVcName, false);
   1623 
   1624   // Create a local stream with a local audio track and adds it to the stats.
   1625   AddOutgoingAudioTrackStats();
   1626   stats.AddStream(stream_);
   1627   stats.AddLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
   1628 
   1629   // Create a remote stream with a remote audio track and adds it to the stats.
   1630   rtc::scoped_refptr<webrtc::MediaStream> remote_stream(
   1631       webrtc::MediaStream::Create("remotestreamlabel"));
   1632   rtc::scoped_refptr<FakeAudioTrack> remote_track(
   1633       new rtc::RefCountedObject<FakeAudioTrack>(kRemoteTrackId));
   1634   EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _))
   1635       .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true)));
   1636   remote_stream->AddTrack(remote_track);
   1637   stats.AddStream(remote_stream);
   1638 
   1639   // Instruct the session to return stats containing the transport channel.
   1640   InitSessionStats(kVcName);
   1641   EXPECT_CALL(session_, GetTransportStats(_))
   1642       .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_),
   1643                             Return(true)));
   1644 
   1645   cricket::VoiceSenderInfo voice_sender_info;
   1646   InitVoiceSenderInfo(&voice_sender_info);
   1647 
   1648   // Some of the contents in |voice_sender_info| needs to be updated from the
   1649   // |audio_track_|.
   1650   UpdateVoiceSenderInfoFromAudioTrack(audio_track_.get(), &voice_sender_info);
   1651 
   1652   cricket::VoiceReceiverInfo voice_receiver_info;
   1653   InitVoiceReceiverInfo(&voice_receiver_info);
   1654 
   1655   // Constructs an ssrc stats update.
   1656   cricket::VoiceMediaInfo stats_read;
   1657   stats_read.senders.push_back(voice_sender_info);
   1658   stats_read.receivers.push_back(voice_receiver_info);
   1659 
   1660   EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel));
   1661   EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
   1662   EXPECT_CALL(*media_channel, GetStats(_))
   1663       .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read),
   1664                             Return(true)));
   1665 
   1666   StatsReports reports;  // returned values.
   1667   stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard);
   1668 
   1669   // Get stats for the local track.
   1670   stats.GetStats(audio_track_.get(), &reports);
   1671   const StatsReport* track_report = FindNthReportByType(
   1672       reports, StatsReport::kStatsReportTypeSsrc, 1);
   1673   EXPECT_TRUE(track_report);
   1674   EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
   1675   std::string track_id = ExtractSsrcStatsValue(
   1676       reports, StatsReport::kStatsValueNameTrackId);
   1677   EXPECT_EQ(kLocalTrackId, track_id);
   1678   VerifyVoiceSenderInfoReport(track_report, voice_sender_info);
   1679 
   1680   // Get stats for the remote track.
   1681   reports.clear();
   1682   stats.GetStats(remote_track.get(), &reports);
   1683   track_report = FindNthReportByType(reports,
   1684                                      StatsReport::kStatsReportTypeSsrc, 1);
   1685   EXPECT_TRUE(track_report);
   1686   EXPECT_EQ(stats.GetTimeNow(), track_report->timestamp());
   1687   track_id = ExtractSsrcStatsValue(reports,
   1688                                    StatsReport::kStatsValueNameTrackId);
   1689   EXPECT_EQ(kRemoteTrackId, track_id);
   1690   VerifyVoiceReceiverInfoReport(track_report, voice_receiver_info);
   1691 }
   1692 
   1693 // This test verifies that when two outgoing audio tracks are using the same
   1694 // ssrc at different times, they populate stats reports correctly.
   1695 // TODO(xians): Figure out if it is possible to encapsulate the setup and
   1696 // avoid duplication of code in test cases.
   1697 TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) {
   1698   StatsCollectorForTest stats(&pc_);
   1699 
   1700   EXPECT_CALL(session_, GetLocalCertificate(_, _))
   1701       .WillRepeatedly(Return(false));
   1702   EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
   1703       .WillRepeatedly(Return(false));
   1704 
   1705   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   1706   // The transport_name known by the voice channel.
   1707   const std::string kVcName("vcname");
   1708   cricket::VoiceChannel voice_channel(rtc::Thread::Current(), media_engine_,
   1709                                       media_channel, nullptr, kVcName, false);
   1710 
   1711   // Create a local stream with a local audio track and adds it to the stats.
   1712   AddOutgoingAudioTrackStats();
   1713   stats.AddStream(stream_);
   1714   stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack);
   1715 
   1716   cricket::VoiceSenderInfo voice_sender_info;
   1717   voice_sender_info.add_ssrc(kSsrcOfTrack);
   1718 
   1719   cricket::VoiceMediaInfo stats_read;
   1720   StatsReports reports;  // returned values.
   1721   SetupAndVerifyAudioTrackStats(
   1722       audio_track_.get(), stream_.get(), &stats, &voice_channel, kVcName,
   1723       media_channel, &voice_sender_info, NULL, &stats_read, &reports);
   1724 
   1725   // Remove the previous audio track from the stream.
   1726   stream_->RemoveTrack(audio_track_.get());
   1727   stats.RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack);
   1728 
   1729   // Create a new audio track and adds it to the stream and stats.
   1730   static const std::string kNewTrackId = "new_track_id";
   1731   rtc::scoped_refptr<FakeAudioTrack> new_audio_track(
   1732       new rtc::RefCountedObject<FakeAudioTrack>(kNewTrackId));
   1733   EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _))
   1734       .WillOnce(DoAll(SetArgPointee<1>(kNewTrackId), Return(true)));
   1735   stream_->AddTrack(new_audio_track);
   1736 
   1737   stats.AddLocalAudioTrack(new_audio_track, kSsrcOfTrack);
   1738   stats.ClearUpdateStatsCacheForTest();
   1739   cricket::VoiceSenderInfo new_voice_sender_info;
   1740   InitVoiceSenderInfo(&new_voice_sender_info);
   1741   cricket::VoiceMediaInfo new_stats_read;
   1742   reports.clear();
   1743   SetupAndVerifyAudioTrackStats(
   1744       new_audio_track.get(), stream_.get(), &stats, &voice_channel, kVcName,
   1745       media_channel, &new_voice_sender_info, NULL, &new_stats_read, &reports);
   1746 }
   1747 
   1748 }  // namespace webrtc
   1749