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