media/webrtc/signaling/test/mediapipeline_unittest.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 // Original author: ekr@rtfm.com
     7 #include <iostream>
     9 #include "sigslot.h"
    11 #include "logging.h"
    12 #include "nsThreadUtils.h"
    13 #include "nsXPCOM.h"
    14 #include "nss.h"
    15 #include "ssl.h"
    16 #include "sslproto.h"
    18 #include "dtlsidentity.h"
    19 #include "mozilla/RefPtr.h"
    20 #include "FakeMediaStreams.h"
    21 #include "FakeMediaStreamsImpl.h"
    22 #include "MediaConduitErrors.h"
    23 #include "MediaConduitInterface.h"
    24 #include "MediaPipeline.h"
    25 #include "MediaPipelineFilter.h"
    26 #include "runnable_utils.h"
    27 #include "transportflow.h"
    28 #include "transportlayerloopback.h"
    29 #include "transportlayerdtls.h"
    30 #include "mozilla/SyncRunnable.h"
    33 #include "mtransport_test_utils.h"
    34 #include "runnable_utils.h"
    36 #include "webrtc/modules/interface/module_common_types.h"
    38 #define GTEST_HAS_RTTI 0
    39 #include "gtest/gtest.h"
    40 #include "gtest_utils.h"
    42 using namespace mozilla;
    43 MOZ_MTLOG_MODULE("mediapipeline")
    45 MtransportTestUtils *test_utils;
    47 namespace {
    49 class TransportInfo {
    50  public:
    51   TransportInfo() :
    52     flow_(nullptr),
    53     loopback_(nullptr),
    54     dtls_(nullptr) {}
    56   static void InitAndConnect(TransportInfo &client, TransportInfo &server) {
    57     client.Init(true);
    58     server.Init(false);
    59     client.PushLayers();
    60     server.PushLayers();
    61     client.Connect(&server);
    62     server.Connect(&client);
    63   }
    65   void Init(bool client) {
    66     nsresult res;
    68     flow_ = new TransportFlow();
    69     loopback_ = new TransportLayerLoopback();
    70     dtls_ = new TransportLayerDtls();
    72     res = loopback_->Init();
    73     if (res != NS_OK) {
    74       FreeLayers();
    75     }
    76     ASSERT_EQ((nsresult)NS_OK, res);
    78     std::vector<uint16_t> ciphers;
    79     ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
    80     dtls_->SetSrtpCiphers(ciphers);
    81     dtls_->SetIdentity(DtlsIdentity::Generate());
    82     dtls_->SetRole(client ? TransportLayerDtls::CLIENT :
    83       TransportLayerDtls::SERVER);
    84     dtls_->SetVerificationAllowAll();
    85   }
    87   void PushLayers() {
    88     nsresult res;
    90     nsAutoPtr<std::queue<TransportLayer *> > layers(
    91       new std::queue<TransportLayer *>);
    92     layers->push(loopback_);
    93     layers->push(dtls_);
    94     res = flow_->PushLayers(layers);
    95     if (res != NS_OK) {
    96       FreeLayers();
    97     }
    98     ASSERT_EQ((nsresult)NS_OK, res);
    99   }
   101   void Connect(TransportInfo* peer) {
   102     MOZ_ASSERT(loopback_);
   103     MOZ_ASSERT(peer->loopback_);
   105     loopback_->Connect(peer->loopback_);
   106   }
   108   // Free the memory allocated at the beginning of Init
   109   // if failure occurs before layers setup.
   110   void FreeLayers() {
   111     delete loopback_;
   112     loopback_ = nullptr;
   113     delete dtls_;
   114     dtls_ = nullptr;
   115   }
   117   void Shutdown() {
   118     if (loopback_) {
   119       loopback_->Disconnect();
   120     }
   121     loopback_ = nullptr;
   122     dtls_ = nullptr;
   123     flow_ = nullptr;
   124   }
   126   mozilla::RefPtr<TransportFlow> flow_;
   127   TransportLayerLoopback *loopback_;
   128   TransportLayerDtls *dtls_;
   129 };
   131 class TestAgent {
   132  public:
   133   TestAgent() :
   134       audio_config_(109, "opus", 48000, 960, 2, 64000),
   135       audio_conduit_(mozilla::AudioSessionConduit::Create(nullptr)),
   136       audio_(),
   137       audio_pipeline_() {
   138   }
   140   static void ConnectRtp(TestAgent *client, TestAgent *server) {
   141     TransportInfo::InitAndConnect(client->audio_rtp_transport_,
   142                                   server->audio_rtp_transport_);
   143   }
   145   static void ConnectRtcp(TestAgent *client, TestAgent *server) {
   146     TransportInfo::InitAndConnect(client->audio_rtcp_transport_,
   147                                   server->audio_rtcp_transport_);
   148   }
   150   static void ConnectBundle(TestAgent *client, TestAgent *server) {
   151     TransportInfo::InitAndConnect(client->bundle_transport_,
   152                                   server->bundle_transport_);
   153   }
   155   virtual void CreatePipelines_s(bool aIsRtcpMux) = 0;
   157   void Start() {
   158     nsresult ret;
   160     MOZ_MTLOG(ML_DEBUG, "Starting");
   162     mozilla::SyncRunnable::DispatchToThread(
   163       test_utils->sts_target(),
   164       WrapRunnableRet(audio_->GetStream(), &Fake_MediaStream::Start, &ret));
   166     ASSERT_TRUE(NS_SUCCEEDED(ret));
   167   }
   169   void StopInt() {
   170     audio_->GetStream()->Stop();
   171   }
   173   void Stop() {
   174     MOZ_MTLOG(ML_DEBUG, "Stopping");
   176     if (audio_pipeline_)
   177       audio_pipeline_->ShutdownMedia_m();
   179     mozilla::SyncRunnable::DispatchToThread(
   180       test_utils->sts_target(),
   181       WrapRunnable(this, &TestAgent::StopInt));
   182   }
   184   void Shutdown_s() {
   185     audio_rtp_transport_.Shutdown();
   186     audio_rtcp_transport_.Shutdown();
   187     bundle_transport_.Shutdown();
   188     if (audio_pipeline_)
   189       audio_pipeline_->ShutdownTransport_s();
   190   }
   192   void Shutdown() {
   193     if (audio_pipeline_)
   194       audio_pipeline_->ShutdownMedia_m();
   196     mozilla::SyncRunnable::DispatchToThread(
   197       test_utils->sts_target(),
   198       WrapRunnable(this, &TestAgent::Shutdown_s));
   199   }
   201   uint32_t GetRemoteSSRC() {
   202     uint32_t res = 0;
   203     audio_conduit_->GetRemoteSSRC(&res);
   204     return res;
   205   }
   207   uint32_t GetLocalSSRC() {
   208     uint32_t res = 0;
   209     audio_conduit_->GetLocalSSRC(&res);
   210     return res;
   211   }
   213   int GetAudioRtpCountSent() {
   214     return audio_pipeline_->rtp_packets_sent();
   215   }
   217   int GetAudioRtpCountReceived() {
   218     return audio_pipeline_->rtp_packets_received();
   219   }
   221   int GetAudioRtcpCountSent() {
   222     return audio_pipeline_->rtcp_packets_sent();
   223   }
   225   int GetAudioRtcpCountReceived() {
   226     return audio_pipeline_->rtcp_packets_received();
   227   }
   229  protected:
   230   mozilla::AudioCodecConfig audio_config_;
   231   mozilla::RefPtr<mozilla::MediaSessionConduit> audio_conduit_;
   232   nsRefPtr<DOMMediaStream> audio_;
   233   // TODO(bcampen@mozilla.com): Right now this does not let us test RTCP in
   234   // both directions; only the sender's RTCP is sent, but the receiver should
   235   // be sending it too.
   236   mozilla::RefPtr<mozilla::MediaPipeline> audio_pipeline_;
   237   TransportInfo audio_rtp_transport_;
   238   TransportInfo audio_rtcp_transport_;
   239   TransportInfo bundle_transport_;
   240 };
   242 class TestAgentSend : public TestAgent {
   243  public:
   244   TestAgentSend() : use_bundle_(false) {}
   246   virtual void CreatePipelines_s(bool aIsRtcpMux) {
   247     audio_ = new Fake_DOMMediaStream(new Fake_AudioStreamSource());
   249     mozilla::MediaConduitErrorCode err =
   250         static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get())->
   251         ConfigureSendMediaCodec(&audio_config_);
   252     EXPECT_EQ(mozilla::kMediaConduitNoError, err);
   254     std::string test_pc("PC");
   256     if (aIsRtcpMux) {
   257       ASSERT_FALSE(audio_rtcp_transport_.flow_);
   258     }
   260     RefPtr<TransportFlow> rtp(audio_rtp_transport_.flow_);
   261     RefPtr<TransportFlow> rtcp(audio_rtcp_transport_.flow_);
   263     if (use_bundle_) {
   264       rtp = bundle_transport_.flow_;
   265       rtcp = nullptr;
   266     }
   268     audio_pipeline_ = new mozilla::MediaPipelineTransmit(
   269         test_pc,
   270         nullptr,
   271         test_utils->sts_target(),
   272         audio_,
   273         1,
   274         1,
   275         audio_conduit_,
   276         rtp,
   277         rtcp);
   279     audio_pipeline_->Init();
   280   }
   282   void SetUsingBundle(bool use_bundle) {
   283     use_bundle_ = use_bundle;
   284   }
   286  private:
   287   bool use_bundle_;
   288 };
   291 class TestAgentReceive : public TestAgent {
   292  public:
   293   virtual void CreatePipelines_s(bool aIsRtcpMux) {
   294     mozilla::SourceMediaStream *audio = new Fake_SourceMediaStream();
   295     audio->SetPullEnabled(true);
   297     mozilla::AudioSegment* segment= new mozilla::AudioSegment();
   298     audio->AddTrack(0, 100, 0, segment);
   299     audio->AdvanceKnownTracksTime(mozilla::STREAM_TIME_MAX);
   301     audio_ = new Fake_DOMMediaStream(audio);
   303     std::vector<mozilla::AudioCodecConfig *> codecs;
   304     codecs.push_back(&audio_config_);
   306     mozilla::MediaConduitErrorCode err =
   307         static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get())->
   308         ConfigureRecvMediaCodecs(codecs);
   309     EXPECT_EQ(mozilla::kMediaConduitNoError, err);
   311     std::string test_pc("PC");
   313     if (aIsRtcpMux) {
   314       ASSERT_FALSE(audio_rtcp_transport_.flow_);
   315     }
   317     // For now, assume bundle always uses rtcp mux
   318     RefPtr<TransportFlow> dummy;
   319     RefPtr<TransportFlow> bundle_transport;
   320     if (bundle_filter_) {
   321       bundle_transport = bundle_transport_.flow_;
   322       bundle_filter_->AddLocalSSRC(GetLocalSSRC());
   323     }
   325     audio_pipeline_ = new mozilla::MediaPipelineReceiveAudio(
   326         test_pc,
   327         nullptr,
   328         test_utils->sts_target(),
   329         audio_->GetStream(), 1, 1,
   330         static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get()),
   331         audio_rtp_transport_.flow_,
   332         audio_rtcp_transport_.flow_,
   333         bundle_transport,
   334         dummy,
   335         bundle_filter_);
   337     audio_pipeline_->Init();
   338   }
   340   void SetBundleFilter(nsAutoPtr<MediaPipelineFilter> filter) {
   341     bundle_filter_ = filter;
   342   }
   344   void SetUsingBundle_s(bool decision) {
   345     audio_pipeline_->SetUsingBundle_s(decision);
   346   }
   348   void UpdateFilterFromRemoteDescription_s(
   349       nsAutoPtr<MediaPipelineFilter> filter) {
   350     audio_pipeline_->UpdateFilterFromRemoteDescription_s(filter);
   351   }
   353  private:
   354   nsAutoPtr<MediaPipelineFilter> bundle_filter_;
   355 };
   358 class MediaPipelineTest : public ::testing::Test {
   359  public:
   360   ~MediaPipelineTest() {
   361     p1_.Stop();
   362     p2_.Stop();
   363     p1_.Shutdown();
   364     p2_.Shutdown();
   365   }
   367   // Setup transport.
   368   void InitTransports(bool aIsRtcpMux) {
   369     // RTP, p1_ is server, p2_ is client
   370     mozilla::SyncRunnable::DispatchToThread(
   371       test_utils->sts_target(),
   372       WrapRunnableNM(&TestAgent::ConnectRtp, &p2_, &p1_));
   374     // Create RTCP flows separately if we are not muxing them.
   375     if(!aIsRtcpMux) {
   376       // RTCP, p1_ is server, p2_ is client
   377       mozilla::SyncRunnable::DispatchToThread(
   378         test_utils->sts_target(),
   379         WrapRunnableNM(&TestAgent::ConnectRtcp, &p2_, &p1_));
   380     }
   382     // BUNDLE, p1_ is server, p2_ is client
   383     mozilla::SyncRunnable::DispatchToThread(
   384       test_utils->sts_target(),
   385       WrapRunnableNM(&TestAgent::ConnectBundle, &p2_, &p1_));
   386   }
   388   // Verify RTP and RTCP
   389   void TestAudioSend(bool aIsRtcpMux,
   390                      bool bundle = false,
   391                      nsAutoPtr<MediaPipelineFilter> localFilter =
   392                         nsAutoPtr<MediaPipelineFilter>(nullptr),
   393                      nsAutoPtr<MediaPipelineFilter> remoteFilter =
   394                         nsAutoPtr<MediaPipelineFilter>(nullptr),
   395                      unsigned int ms_until_answer = 500,
   396                      unsigned int ms_of_traffic_after_answer = 10000) {
   398     // We do not support testing bundle without rtcp mux, since that doesn't
   399     // make any sense.
   400     ASSERT_FALSE(!aIsRtcpMux && bundle);
   402     p1_.SetUsingBundle(bundle);
   403     p2_.SetBundleFilter(localFilter);
   405     // Setup transport flows
   406     InitTransports(aIsRtcpMux);
   408     mozilla::SyncRunnable::DispatchToThread(
   409       test_utils->sts_target(),
   410       WrapRunnable(&p1_, &TestAgent::CreatePipelines_s, aIsRtcpMux));
   412     mozilla::SyncRunnable::DispatchToThread(
   413       test_utils->sts_target(),
   414       WrapRunnable(&p2_, &TestAgent::CreatePipelines_s, aIsRtcpMux));
   416     p2_.Start();
   417     p1_.Start();
   419     // Simulate pre-answer traffic
   420     PR_Sleep(ms_until_answer);
   422     mozilla::SyncRunnable::DispatchToThread(
   423       test_utils->sts_target(),
   424       WrapRunnable(&p2_, &TestAgentReceive::SetUsingBundle_s, bundle));
   426     if (bundle) {
   427       // Leaving remoteFilter not set implies we want to test sunny-day
   428       if (!remoteFilter) {
   429         remoteFilter = new MediaPipelineFilter;
   430         // Might not be safe, strictly speaking.
   431         remoteFilter->AddRemoteSSRC(p1_.GetLocalSSRC());
   432       }
   434       mozilla::SyncRunnable::DispatchToThread(
   435           test_utils->sts_target(),
   436           WrapRunnable(&p2_,
   437                        &TestAgentReceive::UpdateFilterFromRemoteDescription_s,
   438                        remoteFilter));
   439     }
   442     // wait for some RTP/RTCP tx and rx to happen
   443     PR_Sleep(ms_of_traffic_after_answer);
   445     p1_.Stop();
   446     p2_.Stop();
   448     // wait for any packets in flight to arrive
   449     PR_Sleep(100);
   451     p1_.Shutdown();
   452     p2_.Shutdown();
   454     if (!bundle) {
   455       // If we are doing bundle, allow the test-case to do this checking.
   456       ASSERT_GE(p1_.GetAudioRtpCountSent(), 40);
   457       ASSERT_EQ(p1_.GetAudioRtpCountReceived(), p2_.GetAudioRtpCountSent());
   458       ASSERT_EQ(p1_.GetAudioRtpCountSent(), p2_.GetAudioRtpCountReceived());
   460       // Calling ShutdownMedia_m on both pipelines does not stop the flow of
   461       // RTCP. So, we might be off by one here.
   462       ASSERT_LE(p2_.GetAudioRtcpCountReceived(), p1_.GetAudioRtcpCountSent());
   463       ASSERT_GE(p2_.GetAudioRtcpCountReceived() + 1, p1_.GetAudioRtcpCountSent());
   464     }
   466   }
   468   void TestAudioReceiverOffersBundle(bool bundle_accepted,
   469       nsAutoPtr<MediaPipelineFilter> localFilter,
   470       nsAutoPtr<MediaPipelineFilter> remoteFilter =
   471           nsAutoPtr<MediaPipelineFilter>(nullptr),
   472       unsigned int ms_until_answer = 500,
   473       unsigned int ms_of_traffic_after_answer = 10000) {
   474     TestAudioSend(true,
   475                   bundle_accepted,
   476                   localFilter,
   477                   remoteFilter,
   478                   ms_until_answer,
   479                   ms_of_traffic_after_answer);
   480   }
   481 protected:
   482   TestAgentSend p1_;
   483   TestAgentReceive p2_;
   484 };
   486 class MediaPipelineFilterTest : public ::testing::Test {
   487   public:
   488     bool Filter(MediaPipelineFilter& filter,
   489                 int32_t correlator,
   490                 uint32_t ssrc,
   491                 uint8_t payload_type) {
   493       webrtc::RTPHeader header;
   494       header.ssrc = ssrc;
   495       header.payloadType = payload_type;
   496       return filter.Filter(header, correlator);
   497     }
   498 };
   500 TEST_F(MediaPipelineFilterTest, TestConstruct) {
   501   MediaPipelineFilter filter;
   502 }
   504 TEST_F(MediaPipelineFilterTest, TestDefault) {
   505   MediaPipelineFilter filter;
   506   ASSERT_FALSE(Filter(filter, 0, 233, 110));
   507 }
   509 TEST_F(MediaPipelineFilterTest, TestSSRCFilter) {
   510   MediaPipelineFilter filter;
   511   filter.AddRemoteSSRC(555);
   512   ASSERT_TRUE(Filter(filter, 0, 555, 110));
   513   ASSERT_FALSE(Filter(filter, 0, 556, 110));
   514 }
   516 #define SSRC(ssrc) \
   517   ((ssrc >> 24) & 0xFF), \
   518   ((ssrc >> 16) & 0xFF), \
   519   ((ssrc >> 8 ) & 0xFF), \
   520   (ssrc         & 0xFF)
   522 #define REPORT_FRAGMENT(ssrc) \
   523   SSRC(ssrc), \
   524   0,0,0,0, \
   525   0,0,0,0, \
   526   0,0,0,0, \
   527   0,0,0,0, \
   528   0,0,0,0
   530 #define RTCP_TYPEINFO(num_rrs, type, size) \
   531   0x80 + num_rrs, type, 0, size
   533 const unsigned char rtcp_rr_s16[] = {
   534   // zero rrs, size 1 words
   535   RTCP_TYPEINFO(0, MediaPipelineFilter::RECEIVER_REPORT_T, 1),
   536   SSRC(16)
   537 };
   539 const unsigned char rtcp_rr_s16_r17[] = {
   540   // one rr, 7 words
   541   RTCP_TYPEINFO(1, MediaPipelineFilter::RECEIVER_REPORT_T, 7),
   542   SSRC(16),
   543   REPORT_FRAGMENT(17)
   544 };
   546 const unsigned char rtcp_rr_s16_r17_18[] = {
   547   // two rrs, size 13 words
   548   RTCP_TYPEINFO(2, MediaPipelineFilter::RECEIVER_REPORT_T, 13),
   549   SSRC(16),
   550   REPORT_FRAGMENT(17),
   551   REPORT_FRAGMENT(18)
   552 };
   554 const unsigned char rtcp_sr_s16[] = {
   555   // zero rrs, size 6 words
   556   RTCP_TYPEINFO(0, MediaPipelineFilter::SENDER_REPORT_T, 6),
   557   REPORT_FRAGMENT(16)
   558 };
   560 const unsigned char rtcp_sr_s16_r17[] = {
   561   // one rr, size 12 words
   562   RTCP_TYPEINFO(1, MediaPipelineFilter::SENDER_REPORT_T, 12),
   563   REPORT_FRAGMENT(16),
   564   REPORT_FRAGMENT(17)
   565 };
   567 const unsigned char rtcp_sr_s16_r17_18[] = {
   568   // two rrs, size 18 words
   569   RTCP_TYPEINFO(2, MediaPipelineFilter::SENDER_REPORT_T, 18),
   570   REPORT_FRAGMENT(16),
   571   REPORT_FRAGMENT(17),
   572   REPORT_FRAGMENT(18)
   573 };
   575 const unsigned char unknown_type[] = {
   576   RTCP_TYPEINFO(1, 222, 0)
   577 };
   579 TEST_F(MediaPipelineFilterTest, TestEmptyFilterReport0) {
   580   MediaPipelineFilter filter;
   581   ASSERT_EQ(MediaPipelineFilter::FAIL,
   582             filter.FilterRTCP(rtcp_sr_s16, sizeof(rtcp_sr_s16)));
   583   ASSERT_EQ(MediaPipelineFilter::FAIL,
   584             filter.FilterRTCP(rtcp_rr_s16, sizeof(rtcp_rr_s16)));
   585 }
   587 TEST_F(MediaPipelineFilterTest, TestFilterReport0) {
   588   MediaPipelineFilter filter;
   589   filter.AddRemoteSSRC(16);
   590   ASSERT_EQ(MediaPipelineFilter::PASS,
   591             filter.FilterRTCP(rtcp_sr_s16, sizeof(rtcp_sr_s16)));
   592   ASSERT_EQ(MediaPipelineFilter::PASS,
   593             filter.FilterRTCP(rtcp_rr_s16, sizeof(rtcp_rr_s16)));
   594 }
   596 TEST_F(MediaPipelineFilterTest, TestFilterReport0SSRCTruncated) {
   597   MediaPipelineFilter filter;
   598   filter.AddRemoteSSRC(16);
   599   const unsigned char data[] = {
   600     RTCP_TYPEINFO(0, MediaPipelineFilter::RECEIVER_REPORT_T, 1),
   601     0,0,0
   602   };
   603   ASSERT_EQ(MediaPipelineFilter::FAIL,
   604             filter.FilterRTCP(data, sizeof(data)));
   605 }
   607 TEST_F(MediaPipelineFilterTest, TestFilterReport0PTTruncated) {
   608   MediaPipelineFilter filter;
   609   filter.AddRemoteSSRC(16);
   610   const unsigned char data[] = {0x80};
   611   ASSERT_EQ(MediaPipelineFilter::FAIL,
   612             filter.FilterRTCP(data, sizeof(data)));
   613 }
   615 TEST_F(MediaPipelineFilterTest, TestFilterReport0CountTruncated) {
   616   MediaPipelineFilter filter;
   617   filter.AddRemoteSSRC(16);
   618   const unsigned char data[] = {};
   619   ASSERT_EQ(MediaPipelineFilter::FAIL,
   620             filter.FilterRTCP(data, sizeof(data)));
   621 }
   623 TEST_F(MediaPipelineFilterTest, TestFilterReport1BothMatch) {
   624   MediaPipelineFilter filter;
   625   filter.AddRemoteSSRC(16);
   626   filter.AddLocalSSRC(17);
   627   ASSERT_EQ(MediaPipelineFilter::PASS,
   628             filter.FilterRTCP(rtcp_sr_s16_r17, sizeof(rtcp_sr_s16_r17)));
   629   ASSERT_EQ(MediaPipelineFilter::PASS,
   630             filter.FilterRTCP(rtcp_rr_s16_r17, sizeof(rtcp_rr_s16_r17)));
   631 }
   633 TEST_F(MediaPipelineFilterTest, TestFilterReport1SSRCTruncated) {
   634   MediaPipelineFilter filter;
   635   filter.AddRemoteSSRC(16);
   636   filter.AddLocalSSRC(17);
   637   const unsigned char rr[] = {
   638     RTCP_TYPEINFO(1, MediaPipelineFilter::RECEIVER_REPORT_T, 7),
   639     SSRC(16),
   640     0,0,0
   641   };
   642   ASSERT_EQ(MediaPipelineFilter::FAIL,
   643             filter.FilterRTCP(rr, sizeof(rr)));
   644   const unsigned char sr[] = {
   645     RTCP_TYPEINFO(1, MediaPipelineFilter::RECEIVER_REPORT_T, 12),
   646     REPORT_FRAGMENT(16),
   647     0,0,0
   648   };
   649   ASSERT_EQ(MediaPipelineFilter::FAIL,
   650             filter.FilterRTCP(sr, sizeof(rr)));
   651 }
   653 TEST_F(MediaPipelineFilterTest, TestFilterReport1BigSSRC) {
   654   MediaPipelineFilter filter;
   655   filter.AddRemoteSSRC(0x01020304);
   656   filter.AddLocalSSRC(0x11121314);
   657   const unsigned char rr[] = {
   658     RTCP_TYPEINFO(1, MediaPipelineFilter::RECEIVER_REPORT_T, 7),
   659     SSRC(0x01020304),
   660     REPORT_FRAGMENT(0x11121314)
   661   };
   662   ASSERT_EQ(MediaPipelineFilter::PASS,
   663             filter.FilterRTCP(rr, sizeof(rr)));
   664   const unsigned char sr[] = {
   665     RTCP_TYPEINFO(1, MediaPipelineFilter::RECEIVER_REPORT_T, 12),
   666     SSRC(0x01020304),
   667     REPORT_FRAGMENT(0x11121314)
   668   };
   669   ASSERT_EQ(MediaPipelineFilter::PASS,
   670             filter.FilterRTCP(sr, sizeof(rr)));
   671 }
   673 TEST_F(MediaPipelineFilterTest, TestFilterReport1LocalMatch) {
   674   MediaPipelineFilter filter;
   675   filter.AddLocalSSRC(17);
   676   ASSERT_EQ(MediaPipelineFilter::PASS,
   677             filter.FilterRTCP(rtcp_sr_s16_r17, sizeof(rtcp_sr_s16_r17)));
   678   ASSERT_EQ(MediaPipelineFilter::PASS,
   679             filter.FilterRTCP(rtcp_rr_s16_r17, sizeof(rtcp_rr_s16_r17)));
   680 }
   682 TEST_F(MediaPipelineFilterTest, TestFilterReport1Inconsistent) {
   683   MediaPipelineFilter filter;
   684   filter.AddRemoteSSRC(16);
   685   // We assume that the filter is exactly correct in terms of local ssrcs.
   686   // So, when RTCP shows up with a remote SSRC that matches, and a local
   687   // ssrc that doesn't, we assume the other end has messed up and put ssrcs
   688   // from more than one m-line in the packet.
   689   ASSERT_EQ(MediaPipelineFilter::FAIL,
   690             filter.FilterRTCP(rtcp_sr_s16_r17, sizeof(rtcp_sr_s16_r17)));
   691   ASSERT_EQ(MediaPipelineFilter::FAIL,
   692             filter.FilterRTCP(rtcp_rr_s16_r17, sizeof(rtcp_rr_s16_r17)));
   693 }
   695 TEST_F(MediaPipelineFilterTest, TestFilterReport1NeitherMatch) {
   696   MediaPipelineFilter filter;
   697   filter.AddRemoteSSRC(17);
   698   filter.AddLocalSSRC(18);
   699   ASSERT_EQ(MediaPipelineFilter::PASS,
   700             filter.FilterRTCP(rtcp_sr_s16_r17, sizeof(rtcp_sr_s16_r17)));
   701   ASSERT_EQ(MediaPipelineFilter::PASS,
   702             filter.FilterRTCP(rtcp_rr_s16_r17, sizeof(rtcp_rr_s16_r17)));
   703 }
   705 TEST_F(MediaPipelineFilterTest, TestFilterReport2AllMatch) {
   706   MediaPipelineFilter filter;
   707   filter.AddRemoteSSRC(16);
   708   filter.AddLocalSSRC(17);
   709   filter.AddLocalSSRC(18);
   710   ASSERT_EQ(MediaPipelineFilter::PASS,
   711             filter.FilterRTCP(rtcp_sr_s16_r17_18,
   712                               sizeof(rtcp_sr_s16_r17_18)));
   713 }
   715 TEST_F(MediaPipelineFilterTest, TestFilterReport2LocalMatch) {
   716   MediaPipelineFilter filter;
   717   filter.AddLocalSSRC(17);
   718   filter.AddLocalSSRC(18);
   719   ASSERT_EQ(MediaPipelineFilter::PASS,
   720             filter.FilterRTCP(rtcp_sr_s16_r17_18,
   721                               sizeof(rtcp_sr_s16_r17_18)));
   722   ASSERT_EQ(MediaPipelineFilter::PASS,
   723             filter.FilterRTCP(rtcp_rr_s16_r17_18,
   724                               sizeof(rtcp_rr_s16_r17_18)));
   725 }
   727 TEST_F(MediaPipelineFilterTest, TestFilterReport2Inconsistent101) {
   728   MediaPipelineFilter filter;
   729   filter.AddRemoteSSRC(16);
   730   filter.AddLocalSSRC(18);
   731   ASSERT_EQ(MediaPipelineFilter::FAIL,
   732             filter.FilterRTCP(rtcp_sr_s16_r17_18,
   733                               sizeof(rtcp_sr_s16_r17_18)));
   734   ASSERT_EQ(MediaPipelineFilter::FAIL,
   735             filter.FilterRTCP(rtcp_rr_s16_r17_18,
   736                               sizeof(rtcp_rr_s16_r17_18)));
   737 }
   739 TEST_F(MediaPipelineFilterTest, TestFilterReport2Inconsistent001) {
   740   MediaPipelineFilter filter;
   741   filter.AddLocalSSRC(18);
   742   ASSERT_EQ(MediaPipelineFilter::FAIL,
   743             filter.FilterRTCP(rtcp_sr_s16_r17_18,
   744                               sizeof(rtcp_sr_s16_r17_18)));
   745   ASSERT_EQ(MediaPipelineFilter::FAIL,
   746             filter.FilterRTCP(rtcp_rr_s16_r17_18,
   747                               sizeof(rtcp_rr_s16_r17_18)));
   748 }
   750 TEST_F(MediaPipelineFilterTest, TestFilterUnknownRTCPType) {
   751   MediaPipelineFilter filter;
   752   filter.AddLocalSSRC(18);
   753   ASSERT_EQ(MediaPipelineFilter::UNSUPPORTED,
   754             filter.FilterRTCP(unknown_type, sizeof(unknown_type)));
   755 }
   757 TEST_F(MediaPipelineFilterTest, TestCorrelatorFilter) {
   758   MediaPipelineFilter filter;
   759   filter.SetCorrelator(7777);
   760   ASSERT_TRUE(Filter(filter, 7777, 16, 110));
   761   ASSERT_FALSE(Filter(filter, 7778, 17, 110));
   762   // This should also have resulted in the SSRC 16 being added to the filter
   763   ASSERT_TRUE(Filter(filter, 0, 16, 110));
   764   ASSERT_FALSE(Filter(filter, 0, 17, 110));
   766   // rtcp_sr_s16 has 16 as an SSRC
   767   ASSERT_EQ(MediaPipelineFilter::PASS,
   768             filter.FilterRTCP(rtcp_sr_s16, sizeof(rtcp_sr_s16)));
   769   ASSERT_EQ(MediaPipelineFilter::PASS,
   770             filter.FilterRTCP(rtcp_rr_s16, sizeof(rtcp_rr_s16)));
   771 }
   773 TEST_F(MediaPipelineFilterTest, TestPayloadTypeFilter) {
   774   MediaPipelineFilter filter;
   775   filter.AddUniquePT(110);
   776   ASSERT_TRUE(Filter(filter, 0, 555, 110));
   777   ASSERT_FALSE(Filter(filter, 0, 556, 111));
   778 }
   780 TEST_F(MediaPipelineFilterTest, TestPayloadTypeFilterSSRCUpdate) {
   781   MediaPipelineFilter filter;
   782   filter.AddUniquePT(110);
   783   ASSERT_TRUE(Filter(filter, 0, 16, 110));
   785   // rtcp_sr_s16 has 16 as an SSRC
   786   ASSERT_EQ(MediaPipelineFilter::PASS,
   787             filter.FilterRTCP(rtcp_sr_s16, sizeof(rtcp_sr_s16)));
   788 }
   790 TEST_F(MediaPipelineFilterTest, TestAnswerAddsSSRCs) {
   791   MediaPipelineFilter filter;
   792   filter.SetCorrelator(7777);
   793   ASSERT_TRUE(Filter(filter, 7777, 555, 110));
   794   ASSERT_FALSE(Filter(filter, 7778, 556, 110));
   795   // This should also have resulted in the SSRC 555 being added to the filter
   796   ASSERT_TRUE(Filter(filter, 0, 555, 110));
   797   ASSERT_FALSE(Filter(filter, 0, 556, 110));
   799   // This sort of thing can happen when getting an answer with SSRC attrs
   800   // The answer will not contain the correlator.
   801   MediaPipelineFilter filter2;
   802   filter2.AddRemoteSSRC(555);
   803   filter2.AddRemoteSSRC(556);
   804   filter2.AddRemoteSSRC(557);
   806   filter.IncorporateRemoteDescription(filter2);
   808   // Ensure that the old SSRC still works.
   809   ASSERT_TRUE(Filter(filter, 0, 555, 110));
   811   // Ensure that the new SSRCs work.
   812   ASSERT_TRUE(Filter(filter, 0, 556, 110));
   813   ASSERT_TRUE(Filter(filter, 0, 557, 110));
   815   // Ensure that the correlator continues to work
   816   ASSERT_TRUE(Filter(filter, 7777, 558, 110));
   817 }
   819 TEST_F(MediaPipelineFilterTest, TestSSRCMovedWithSDP) {
   820   MediaPipelineFilter filter;
   821   filter.SetCorrelator(7777);
   822   filter.AddUniquePT(111);
   823   ASSERT_TRUE(Filter(filter, 7777, 555, 110));
   825   MediaPipelineFilter filter2;
   826   filter2.AddRemoteSSRC(556);
   828   filter.IncorporateRemoteDescription(filter2);
   830   // Ensure that the old SSRC has been removed.
   831   ASSERT_FALSE(Filter(filter, 0, 555, 110));
   833   // Ensure that the new SSRC works.
   834   ASSERT_TRUE(Filter(filter, 0, 556, 110));
   836   // Ensure that the correlator continues to work
   837   ASSERT_TRUE(Filter(filter, 7777, 558, 110));
   839   // Ensure that the payload type mapping continues to work
   840   ASSERT_TRUE(Filter(filter, 0, 559, 111));
   841 }
   843 TEST_F(MediaPipelineFilterTest, TestSSRCMovedWithCorrelator) {
   844   MediaPipelineFilter filter;
   845   filter.SetCorrelator(7777);
   846   ASSERT_TRUE(Filter(filter, 7777, 555, 110));
   847   ASSERT_TRUE(Filter(filter, 0, 555, 110));
   848   ASSERT_FALSE(Filter(filter, 7778, 555, 110));
   849   ASSERT_FALSE(Filter(filter, 0, 555, 110));
   850 }
   852 TEST_F(MediaPipelineFilterTest, TestRemoteSDPNoSSRCs) {
   853   // If the remote SDP doesn't have SSRCs, right now this is a no-op and
   854   // there is no point of even incorporating a filter, but we make the
   855   // behavior consistent to avoid confusion.
   856   MediaPipelineFilter filter;
   857   filter.SetCorrelator(7777);
   858   filter.AddUniquePT(111);
   859   ASSERT_TRUE(Filter(filter, 7777, 555, 110));
   861   MediaPipelineFilter filter2;
   863   filter.IncorporateRemoteDescription(filter2);
   865   // Ensure that the old SSRC still works.
   866   ASSERT_TRUE(Filter(filter, 7777, 555, 110));
   867 }
   869 TEST_F(MediaPipelineTest, TestAudioSendNoMux) {
   870   TestAudioSend(false);
   871 }
   873 TEST_F(MediaPipelineTest, TestAudioSendMux) {
   874   TestAudioSend(true);
   875 }
   877 TEST_F(MediaPipelineTest, TestAudioSendBundleOfferedAndDeclined) {
   878   nsAutoPtr<MediaPipelineFilter> filter(new MediaPipelineFilter);
   879   TestAudioReceiverOffersBundle(false, filter);
   880 }
   882 TEST_F(MediaPipelineTest, TestAudioSendBundleOfferedAndAccepted) {
   883   nsAutoPtr<MediaPipelineFilter> filter(new MediaPipelineFilter);
   884   // These durations have to be _extremely_ long to have any assurance that
   885   // some RTCP will be sent at all. This is because the first RTCP packet
   886   // is sometimes sent before the transports are ready, which causes it to
   887   // be dropped.
   888   TestAudioReceiverOffersBundle(true,
   889                                 filter,
   890   // We do not specify the filter for the remote description, so it will be
   891   // set to something sane after a short time.
   892                                 nsAutoPtr<MediaPipelineFilter>(),
   893                                 10000,
   894                                 10000);
   896   // Some packets should have been dropped, but not all
   897   ASSERT_GT(p1_.GetAudioRtpCountSent(), p2_.GetAudioRtpCountReceived());
   898   ASSERT_GT(p2_.GetAudioRtpCountReceived(), 40);
   899   ASSERT_GT(p1_.GetAudioRtcpCountSent(), 1);
   900   ASSERT_GT(p1_.GetAudioRtcpCountSent(), p2_.GetAudioRtcpCountReceived());
   901   ASSERT_GT(p2_.GetAudioRtcpCountReceived(), 0);
   902 }
   904 TEST_F(MediaPipelineTest, TestAudioSendBundleOfferedAndAcceptedEmptyFilter) {
   905   nsAutoPtr<MediaPipelineFilter> filter(new MediaPipelineFilter);
   906   nsAutoPtr<MediaPipelineFilter> bad_answer_filter(new MediaPipelineFilter);
   907   TestAudioReceiverOffersBundle(true, filter, bad_answer_filter);
   908   // Filter is empty, so should drop everything.
   909   ASSERT_EQ(0, p2_.GetAudioRtpCountReceived());
   910   ASSERT_EQ(0, p2_.GetAudioRtcpCountReceived());
   911 }
   913 }  // end namespace
   916 int main(int argc, char **argv) {
   917   test_utils = new MtransportTestUtils();
   918   // Start the tests
   919   NSS_NoDB_Init(nullptr);
   920   NSS_SetDomesticPolicy();
   921   ::testing::InitGoogleTest(&argc, argv);
   923   int rv = RUN_ALL_TESTS();
   924   delete test_utils;
   925   return rv;
   926 }

mercurial