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