Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2013 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 "talk/app/webrtc/test/peerconnectiontestwrapper.h"
     29 #include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
     30 #ifdef WEBRTC_ANDROID
     31 #include "talk/app/webrtc/test/androidtestinitializer.h"
     32 #endif
     33 #include "webrtc/base/gunit.h"
     34 #include "webrtc/base/logging.h"
     35 #include "webrtc/base/ssladapter.h"
     36 #include "webrtc/base/sslstreamadapter.h"
     37 #include "webrtc/base/stringencode.h"
     38 #include "webrtc/base/stringutils.h"
     39 
     40 #define MAYBE_SKIP_TEST(feature)                    \
     41   if (!(feature())) {                               \
     42     LOG(LS_INFO) << "Feature disabled... skipping"; \
     43     return;                                         \
     44   }
     45 
     46 using webrtc::DataChannelInterface;
     47 using webrtc::FakeConstraints;
     48 using webrtc::MediaConstraintsInterface;
     49 using webrtc::MediaStreamInterface;
     50 using webrtc::PeerConnectionInterface;
     51 
     52 namespace {
     53 
     54 const size_t kMaxWait = 10000;
     55 
     56 }  // namespace
     57 
     58 class PeerConnectionEndToEndTest
     59     : public sigslot::has_slots<>,
     60       public testing::Test {
     61  public:
     62   typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
     63       DataChannelList;
     64 
     65   PeerConnectionEndToEndTest()
     66       : caller_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
     67                     "caller")),
     68         callee_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
     69                     "callee")) {
     70 #ifdef WEBRTC_ANDROID
     71     webrtc::InitializeAndroidObjects();
     72 #endif
     73   }
     74 
     75   void CreatePcs() {
     76     CreatePcs(NULL);
     77   }
     78 
     79   void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
     80     EXPECT_TRUE(caller_->CreatePc(pc_constraints));
     81     EXPECT_TRUE(callee_->CreatePc(pc_constraints));
     82     PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
     83 
     84     caller_->SignalOnDataChannel.connect(
     85         this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
     86     callee_->SignalOnDataChannel.connect(
     87         this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
     88   }
     89 
     90   void GetAndAddUserMedia() {
     91     FakeConstraints audio_constraints;
     92     FakeConstraints video_constraints;
     93     GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
     94   }
     95 
     96   void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
     97                           bool video, FakeConstraints video_constraints) {
     98     caller_->GetAndAddUserMedia(audio, audio_constraints,
     99                                 video, video_constraints);
    100     callee_->GetAndAddUserMedia(audio, audio_constraints,
    101                                 video, video_constraints);
    102   }
    103 
    104   void Negotiate() {
    105     caller_->CreateOffer(NULL);
    106   }
    107 
    108   void WaitForCallEstablished() {
    109     caller_->WaitForCallEstablished();
    110     callee_->WaitForCallEstablished();
    111   }
    112 
    113   void WaitForConnection() {
    114     caller_->WaitForConnection();
    115     callee_->WaitForConnection();
    116   }
    117 
    118   void OnCallerAddedDataChanel(DataChannelInterface* dc) {
    119     caller_signaled_data_channels_.push_back(dc);
    120   }
    121 
    122   void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
    123     callee_signaled_data_channels_.push_back(dc);
    124   }
    125 
    126   // Tests that |dc1| and |dc2| can send to and receive from each other.
    127   void TestDataChannelSendAndReceive(
    128       DataChannelInterface* dc1, DataChannelInterface* dc2) {
    129     rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc1_observer(
    130         new webrtc::MockDataChannelObserver(dc1));
    131 
    132     rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc2_observer(
    133         new webrtc::MockDataChannelObserver(dc2));
    134 
    135     static const std::string kDummyData = "abcdefg";
    136     webrtc::DataBuffer buffer(kDummyData);
    137     EXPECT_TRUE(dc1->Send(buffer));
    138     EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
    139 
    140     EXPECT_TRUE(dc2->Send(buffer));
    141     EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
    142 
    143     EXPECT_EQ(1U, dc1_observer->received_message_count());
    144     EXPECT_EQ(1U, dc2_observer->received_message_count());
    145   }
    146 
    147   void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
    148                                  const DataChannelList& remote_dc_list,
    149                                  size_t remote_dc_index) {
    150     EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
    151 
    152     EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
    153     EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
    154                    remote_dc_list[remote_dc_index]->state(),
    155                    kMaxWait);
    156     EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
    157   }
    158 
    159   void CloseDataChannels(DataChannelInterface* local_dc,
    160                          const DataChannelList& remote_dc_list,
    161                          size_t remote_dc_index) {
    162     local_dc->Close();
    163     EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
    164     EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
    165                    remote_dc_list[remote_dc_index]->state(),
    166                    kMaxWait);
    167   }
    168 
    169  protected:
    170   rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
    171   rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
    172   DataChannelList caller_signaled_data_channels_;
    173   DataChannelList callee_signaled_data_channels_;
    174 };
    175 
    176 // Disabled for TSan v2, see
    177 // https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
    178 // Disabled for Mac, see
    179 // https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
    180 #if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
    181 TEST_F(PeerConnectionEndToEndTest, Call) {
    182   CreatePcs();
    183   GetAndAddUserMedia();
    184   Negotiate();
    185   WaitForCallEstablished();
    186 }
    187 #endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
    188 
    189 TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
    190   FakeConstraints pc_constraints;
    191   pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
    192                               false);
    193   CreatePcs(&pc_constraints);
    194   GetAndAddUserMedia();
    195   Negotiate();
    196   WaitForCallEstablished();
    197 }
    198 
    199 // Verifies that a DataChannel created before the negotiation can transition to
    200 // "OPEN" and transfer data.
    201 TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
    202   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    203 
    204   CreatePcs();
    205 
    206   webrtc::DataChannelInit init;
    207   rtc::scoped_refptr<DataChannelInterface> caller_dc(
    208       caller_->CreateDataChannel("data", init));
    209   rtc::scoped_refptr<DataChannelInterface> callee_dc(
    210       callee_->CreateDataChannel("data", init));
    211 
    212   Negotiate();
    213   WaitForConnection();
    214 
    215   WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
    216   WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
    217 
    218   TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
    219   TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
    220 
    221   CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
    222   CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
    223 }
    224 
    225 // Verifies that a DataChannel created after the negotiation can transition to
    226 // "OPEN" and transfer data.
    227 #if defined(MEMORY_SANITIZER)
    228 // Fails under MemorySanitizer:
    229 // See https://code.google.com/p/webrtc/issues/detail?id=3980.
    230 #define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
    231 #else
    232 #define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
    233 #endif
    234 TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
    235   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    236 
    237   CreatePcs();
    238 
    239   webrtc::DataChannelInit init;
    240 
    241   // This DataChannel is for creating the data content in the negotiation.
    242   rtc::scoped_refptr<DataChannelInterface> dummy(
    243       caller_->CreateDataChannel("data", init));
    244   Negotiate();
    245   WaitForConnection();
    246 
    247   // Creates new DataChannels after the negotiation and verifies their states.
    248   rtc::scoped_refptr<DataChannelInterface> caller_dc(
    249       caller_->CreateDataChannel("hello", init));
    250   rtc::scoped_refptr<DataChannelInterface> callee_dc(
    251       callee_->CreateDataChannel("hello", init));
    252 
    253   WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
    254   WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
    255 
    256   TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
    257   TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
    258 
    259   CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
    260   CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
    261 }
    262 
    263 // Verifies that DataChannel IDs are even/odd based on the DTLS roles.
    264 TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
    265   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    266 
    267   CreatePcs();
    268 
    269   webrtc::DataChannelInit init;
    270   rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
    271       caller_->CreateDataChannel("data", init));
    272   rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
    273       callee_->CreateDataChannel("data", init));
    274 
    275   Negotiate();
    276   WaitForConnection();
    277 
    278   EXPECT_EQ(1U, caller_dc_1->id() % 2);
    279   EXPECT_EQ(0U, callee_dc_1->id() % 2);
    280 
    281   rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
    282       caller_->CreateDataChannel("data", init));
    283   rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
    284       callee_->CreateDataChannel("data", init));
    285 
    286   EXPECT_EQ(1U, caller_dc_2->id() % 2);
    287   EXPECT_EQ(0U, callee_dc_2->id() % 2);
    288 }
    289 
    290 // Verifies that the message is received by the right remote DataChannel when
    291 // there are multiple DataChannels.
    292 TEST_F(PeerConnectionEndToEndTest,
    293        MessageTransferBetweenTwoPairsOfDataChannels) {
    294   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    295 
    296   CreatePcs();
    297 
    298   webrtc::DataChannelInit init;
    299 
    300   rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
    301       caller_->CreateDataChannel("data", init));
    302   rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
    303       caller_->CreateDataChannel("data", init));
    304 
    305   Negotiate();
    306   WaitForConnection();
    307   WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
    308   WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
    309 
    310   rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
    311       new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
    312 
    313   rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
    314       new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
    315 
    316   const std::string message_1 = "hello 1";
    317   const std::string message_2 = "hello 2";
    318 
    319   caller_dc_1->Send(webrtc::DataBuffer(message_1));
    320   EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
    321 
    322   caller_dc_2->Send(webrtc::DataBuffer(message_2));
    323   EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
    324 
    325   EXPECT_EQ(1U, dc_1_observer->received_message_count());
    326   EXPECT_EQ(1U, dc_2_observer->received_message_count());
    327 }
    328 
    329 // Verifies that a DataChannel added from an OPEN message functions after
    330 // a channel has been previously closed (webrtc issue 3778).
    331 // This previously failed because the new channel re-uses the ID of the closed
    332 // channel, and the closed channel was incorrectly still assigned to the id.
    333 // TODO(deadbeef): This is disabled because there's currently a race condition
    334 // caused by the fact that a data channel signals that it's closed before it
    335 // really is. Re-enable this test once that's fixed.
    336 TEST_F(PeerConnectionEndToEndTest,
    337        DISABLED_DataChannelFromOpenWorksAfterClose) {
    338   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    339 
    340   CreatePcs();
    341 
    342   webrtc::DataChannelInit init;
    343   rtc::scoped_refptr<DataChannelInterface> caller_dc(
    344       caller_->CreateDataChannel("data", init));
    345 
    346   Negotiate();
    347   WaitForConnection();
    348 
    349   WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
    350   CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
    351 
    352   // Create a new channel and ensure it works after closing the previous one.
    353   caller_dc = caller_->CreateDataChannel("data2", init);
    354 
    355   WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
    356   TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
    357 
    358   CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
    359 }
    360 
    361 // This tests that if a data channel is closed remotely while not referenced
    362 // by the application (meaning only the PeerConnection contributes to its
    363 // reference count), no memory access violation will occur.
    364 // See: https://code.google.com/p/chromium/issues/detail?id=565048
    365 TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
    366   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
    367 
    368   CreatePcs();
    369 
    370   webrtc::DataChannelInit init;
    371   rtc::scoped_refptr<DataChannelInterface> caller_dc(
    372       caller_->CreateDataChannel("data", init));
    373 
    374   Negotiate();
    375   WaitForConnection();
    376 
    377   WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
    378   // This removes the reference to the remote data channel that we hold.
    379   callee_signaled_data_channels_.clear();
    380   caller_dc->Close();
    381   EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
    382 
    383   // Wait for a bit longer so the remote data channel will receive the
    384   // close message and be destroyed.
    385   rtc::Thread::Current()->ProcessMessages(100);
    386 }
    387