1/* 2 * libjingle 3 * Copyright 2012, 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 <string> 29 30#include "talk/app/webrtc/fakeportallocatorfactory.h" 31#include "talk/app/webrtc/jsepsessiondescription.h" 32#include "talk/app/webrtc/mediastreaminterface.h" 33#include "talk/app/webrtc/peerconnectioninterface.h" 34#include "talk/app/webrtc/test/fakeconstraints.h" 35#include "talk/app/webrtc/test/fakedtlsidentityservice.h" 36#include "talk/app/webrtc/test/mockpeerconnectionobservers.h" 37#include "talk/app/webrtc/test/testsdpstrings.h" 38#include "talk/app/webrtc/videosource.h" 39#include "talk/base/gunit.h" 40#include "talk/base/scoped_ptr.h" 41#include "talk/base/ssladapter.h" 42#include "talk/base/sslstreamadapter.h" 43#include "talk/base/stringutils.h" 44#include "talk/base/thread.h" 45#include "talk/media/base/fakevideocapturer.h" 46#include "talk/media/sctp/sctpdataengine.h" 47#include "talk/session/media/mediasession.h" 48 49static const char kStreamLabel1[] = "local_stream_1"; 50static const char kStreamLabel2[] = "local_stream_2"; 51static const char kStreamLabel3[] = "local_stream_3"; 52static const int kDefaultStunPort = 3478; 53static const char kStunAddressOnly[] = "stun:address"; 54static const char kStunInvalidPort[] = "stun:address:-1"; 55static const char kStunAddressPortAndMore1[] = "stun:address:port:more"; 56static const char kStunAddressPortAndMore2[] = "stun:address:port more"; 57static const char kTurnIceServerUri[] = "turn:user@turn.example.org"; 58static const char kTurnUsername[] = "user"; 59static const char kTurnPassword[] = "password"; 60static const char kTurnHostname[] = "turn.example.org"; 61static const uint32 kTimeout = 5000U; 62 63#define MAYBE_SKIP_TEST(feature) \ 64 if (!(feature())) { \ 65 LOG(LS_INFO) << "Feature disabled... skipping"; \ 66 return; \ 67 } 68 69using talk_base::scoped_ptr; 70using talk_base::scoped_refptr; 71using webrtc::AudioSourceInterface; 72using webrtc::AudioTrackInterface; 73using webrtc::DataBuffer; 74using webrtc::DataChannelInterface; 75using webrtc::FakeConstraints; 76using webrtc::FakePortAllocatorFactory; 77using webrtc::IceCandidateInterface; 78using webrtc::MediaStreamInterface; 79using webrtc::MediaStreamTrackInterface; 80using webrtc::MockCreateSessionDescriptionObserver; 81using webrtc::MockDataChannelObserver; 82using webrtc::MockSetSessionDescriptionObserver; 83using webrtc::MockStatsObserver; 84using webrtc::PeerConnectionInterface; 85using webrtc::PeerConnectionObserver; 86using webrtc::PortAllocatorFactoryInterface; 87using webrtc::SdpParseError; 88using webrtc::SessionDescriptionInterface; 89using webrtc::VideoSourceInterface; 90using webrtc::VideoTrackInterface; 91 92namespace { 93 94// Gets the first ssrc of given content type from the ContentInfo. 95bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) { 96 if (!content_info || !ssrc) { 97 return false; 98 } 99 const cricket::MediaContentDescription* media_desc = 100 static_cast<const cricket::MediaContentDescription*>( 101 content_info->description); 102 if (!media_desc || media_desc->streams().empty()) { 103 return false; 104 } 105 *ssrc = media_desc->streams().begin()->first_ssrc(); 106 return true; 107} 108 109void SetSsrcToZero(std::string* sdp) { 110 const char kSdpSsrcAtribute[] = "a=ssrc:"; 111 const char kSdpSsrcAtributeZero[] = "a=ssrc:0"; 112 size_t ssrc_pos = 0; 113 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) != 114 std::string::npos) { 115 size_t end_ssrc = sdp->find(" ", ssrc_pos); 116 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero); 117 ssrc_pos = end_ssrc; 118 } 119} 120 121class MockPeerConnectionObserver : public PeerConnectionObserver { 122 public: 123 MockPeerConnectionObserver() 124 : renegotiation_needed_(false), 125 ice_complete_(false) { 126 } 127 ~MockPeerConnectionObserver() { 128 } 129 void SetPeerConnectionInterface(PeerConnectionInterface* pc) { 130 pc_ = pc; 131 if (pc) { 132 state_ = pc_->signaling_state(); 133 } 134 } 135 virtual void OnError() {} 136 virtual void OnSignalingChange( 137 PeerConnectionInterface::SignalingState new_state) { 138 EXPECT_EQ(pc_->signaling_state(), new_state); 139 state_ = new_state; 140 } 141 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange. 142 virtual void OnStateChange(StateType state_changed) { 143 if (pc_.get() == NULL) 144 return; 145 switch (state_changed) { 146 case kSignalingState: 147 // OnSignalingChange and OnStateChange(kSignalingState) should always 148 // be called approximately simultaneously. To ease testing, we require 149 // that they always be called in that order. This check verifies 150 // that OnSignalingChange has just been called. 151 EXPECT_EQ(pc_->signaling_state(), state_); 152 break; 153 case kIceState: 154 ADD_FAILURE(); 155 break; 156 default: 157 ADD_FAILURE(); 158 break; 159 } 160 } 161 virtual void OnAddStream(MediaStreamInterface* stream) { 162 last_added_stream_ = stream; 163 } 164 virtual void OnRemoveStream(MediaStreamInterface* stream) { 165 last_removed_stream_ = stream; 166 } 167 virtual void OnRenegotiationNeeded() { 168 renegotiation_needed_ = true; 169 } 170 virtual void OnDataChannel(DataChannelInterface* data_channel) { 171 last_datachannel_ = data_channel; 172 } 173 174 virtual void OnIceConnectionChange( 175 PeerConnectionInterface::IceConnectionState new_state) { 176 EXPECT_EQ(pc_->ice_connection_state(), new_state); 177 } 178 virtual void OnIceGatheringChange( 179 PeerConnectionInterface::IceGatheringState new_state) { 180 EXPECT_EQ(pc_->ice_gathering_state(), new_state); 181 } 182 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { 183 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, 184 pc_->ice_gathering_state()); 185 186 std::string sdp; 187 EXPECT_TRUE(candidate->ToString(&sdp)); 188 EXPECT_LT(0u, sdp.size()); 189 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(), 190 candidate->sdp_mline_index(), sdp, NULL)); 191 EXPECT_TRUE(last_candidate_.get() != NULL); 192 } 193 // TODO(bemasc): Remove this once callers transition to OnSignalingChange. 194 virtual void OnIceComplete() { 195 ice_complete_ = true; 196 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should 197 // be called approximately simultaneously. For ease of testing, this 198 // check additionally requires that they be called in the above order. 199 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 200 pc_->ice_gathering_state()); 201 } 202 203 // Returns the label of the last added stream. 204 // Empty string if no stream have been added. 205 std::string GetLastAddedStreamLabel() { 206 if (last_added_stream_.get()) 207 return last_added_stream_->label(); 208 return ""; 209 } 210 std::string GetLastRemovedStreamLabel() { 211 if (last_removed_stream_.get()) 212 return last_removed_stream_->label(); 213 return ""; 214 } 215 216 scoped_refptr<PeerConnectionInterface> pc_; 217 PeerConnectionInterface::SignalingState state_; 218 scoped_ptr<IceCandidateInterface> last_candidate_; 219 scoped_refptr<DataChannelInterface> last_datachannel_; 220 bool renegotiation_needed_; 221 bool ice_complete_; 222 223 private: 224 scoped_refptr<MediaStreamInterface> last_added_stream_; 225 scoped_refptr<MediaStreamInterface> last_removed_stream_; 226}; 227 228} // namespace 229class PeerConnectionInterfaceTest : public testing::Test { 230 protected: 231 virtual void SetUp() { 232 talk_base::InitializeSSL(NULL); 233 pc_factory_ = webrtc::CreatePeerConnectionFactory( 234 talk_base::Thread::Current(), talk_base::Thread::Current(), NULL, NULL, 235 NULL); 236 ASSERT_TRUE(pc_factory_.get() != NULL); 237 } 238 239 virtual void TearDown() { 240 talk_base::CleanupSSL(); 241 } 242 243 void CreatePeerConnection() { 244 CreatePeerConnection("", "", NULL); 245 } 246 247 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) { 248 CreatePeerConnection("", "", constraints); 249 } 250 251 void CreatePeerConnection(const std::string& uri, 252 const std::string& password, 253 webrtc::MediaConstraintsInterface* constraints) { 254 PeerConnectionInterface::IceServer server; 255 PeerConnectionInterface::IceServers servers; 256 server.uri = uri; 257 server.password = password; 258 servers.push_back(server); 259 260 port_allocator_factory_ = FakePortAllocatorFactory::Create(); 261 262 // DTLS does not work in a loopback call, so is disabled for most of the 263 // tests in this file. We only create a FakeIdentityService if the test 264 // explicitly sets the constraint. 265 FakeIdentityService* dtls_service = NULL; 266 bool dtls; 267 if (FindConstraint(constraints, 268 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 269 &dtls, 270 NULL) && dtls) { 271 dtls_service = new FakeIdentityService(); 272 } 273 pc_ = pc_factory_->CreatePeerConnection(servers, constraints, 274 port_allocator_factory_.get(), 275 dtls_service, 276 &observer_); 277 ASSERT_TRUE(pc_.get() != NULL); 278 observer_.SetPeerConnectionInterface(pc_.get()); 279 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 280 } 281 282 void CreatePeerConnectionWithDifferentConfigurations() { 283 CreatePeerConnection(kStunAddressOnly, "", NULL); 284 EXPECT_EQ(1u, port_allocator_factory_->stun_configs().size()); 285 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 286 EXPECT_EQ("address", 287 port_allocator_factory_->stun_configs()[0].server.hostname()); 288 EXPECT_EQ(kDefaultStunPort, 289 port_allocator_factory_->stun_configs()[0].server.port()); 290 291 CreatePeerConnection(kStunInvalidPort, "", NULL); 292 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 293 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 294 295 CreatePeerConnection(kStunAddressPortAndMore1, "", NULL); 296 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 297 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 298 299 CreatePeerConnection(kStunAddressPortAndMore2, "", NULL); 300 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 301 EXPECT_EQ(0u, port_allocator_factory_->turn_configs().size()); 302 303 CreatePeerConnection(kTurnIceServerUri, kTurnPassword, NULL); 304 EXPECT_EQ(0u, port_allocator_factory_->stun_configs().size()); 305 EXPECT_EQ(1u, port_allocator_factory_->turn_configs().size()); 306 EXPECT_EQ(kTurnUsername, 307 port_allocator_factory_->turn_configs()[0].username); 308 EXPECT_EQ(kTurnPassword, 309 port_allocator_factory_->turn_configs()[0].password); 310 EXPECT_EQ(kTurnHostname, 311 port_allocator_factory_->turn_configs()[0].server.hostname()); 312 } 313 314 void ReleasePeerConnection() { 315 pc_ = NULL; 316 observer_.SetPeerConnectionInterface(NULL); 317 } 318 319 void AddStream(const std::string& label) { 320 // Create a local stream. 321 scoped_refptr<MediaStreamInterface> stream( 322 pc_factory_->CreateLocalMediaStream(label)); 323 scoped_refptr<VideoSourceInterface> video_source( 324 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); 325 scoped_refptr<VideoTrackInterface> video_track( 326 pc_factory_->CreateVideoTrack(label + "v0", video_source)); 327 stream->AddTrack(video_track.get()); 328 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 329 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 330 observer_.renegotiation_needed_ = false; 331 } 332 333 void AddVoiceStream(const std::string& label) { 334 // Create a local stream. 335 scoped_refptr<MediaStreamInterface> stream( 336 pc_factory_->CreateLocalMediaStream(label)); 337 scoped_refptr<AudioTrackInterface> audio_track( 338 pc_factory_->CreateAudioTrack(label + "a0", NULL)); 339 stream->AddTrack(audio_track.get()); 340 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 341 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 342 observer_.renegotiation_needed_ = false; 343 } 344 345 void AddAudioVideoStream(const std::string& stream_label, 346 const std::string& audio_track_label, 347 const std::string& video_track_label) { 348 // Create a local stream. 349 scoped_refptr<MediaStreamInterface> stream( 350 pc_factory_->CreateLocalMediaStream(stream_label)); 351 scoped_refptr<AudioTrackInterface> audio_track( 352 pc_factory_->CreateAudioTrack( 353 audio_track_label, static_cast<AudioSourceInterface*>(NULL))); 354 stream->AddTrack(audio_track.get()); 355 scoped_refptr<VideoTrackInterface> video_track( 356 pc_factory_->CreateVideoTrack(video_track_label, NULL)); 357 stream->AddTrack(video_track.get()); 358 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 359 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); 360 observer_.renegotiation_needed_ = false; 361 } 362 363 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, bool offer) { 364 talk_base::scoped_refptr<MockCreateSessionDescriptionObserver> 365 observer(new talk_base::RefCountedObject< 366 MockCreateSessionDescriptionObserver>()); 367 if (offer) { 368 pc_->CreateOffer(observer, NULL); 369 } else { 370 pc_->CreateAnswer(observer, NULL); 371 } 372 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 373 *desc = observer->release_desc(); 374 return observer->result(); 375 } 376 377 bool DoCreateOffer(SessionDescriptionInterface** desc) { 378 return DoCreateOfferAnswer(desc, true); 379 } 380 381 bool DoCreateAnswer(SessionDescriptionInterface** desc) { 382 return DoCreateOfferAnswer(desc, false); 383 } 384 385 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) { 386 talk_base::scoped_refptr<MockSetSessionDescriptionObserver> 387 observer(new talk_base::RefCountedObject< 388 MockSetSessionDescriptionObserver>()); 389 if (local) { 390 pc_->SetLocalDescription(observer, desc); 391 } else { 392 pc_->SetRemoteDescription(observer, desc); 393 } 394 EXPECT_EQ_WAIT(true, observer->called(), kTimeout); 395 return observer->result(); 396 } 397 398 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { 399 return DoSetSessionDescription(desc, true); 400 } 401 402 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { 403 return DoSetSessionDescription(desc, false); 404 } 405 406 // Calls PeerConnection::GetStats and check the return value. 407 // It does not verify the values in the StatReports since a RTCP packet might 408 // be required. 409 bool DoGetStats(MediaStreamTrackInterface* track) { 410 talk_base::scoped_refptr<MockStatsObserver> observer( 411 new talk_base::RefCountedObject<MockStatsObserver>()); 412 if (!pc_->GetStats( 413 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)) 414 return false; 415 EXPECT_TRUE_WAIT(observer->called(), kTimeout); 416 return observer->called(); 417 } 418 419 void InitiateCall() { 420 CreatePeerConnection(); 421 // Create a local stream with audio&video tracks. 422 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 423 CreateOfferReceiveAnswer(); 424 } 425 426 // Verify that RTP Header extensions has been negotiated for audio and video. 427 void VerifyRemoteRtpHeaderExtensions() { 428 const cricket::MediaContentDescription* desc = 429 cricket::GetFirstAudioContentDescription( 430 pc_->remote_description()->description()); 431 ASSERT_TRUE(desc != NULL); 432 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 433 434 desc = cricket::GetFirstVideoContentDescription( 435 pc_->remote_description()->description()); 436 ASSERT_TRUE(desc != NULL); 437 EXPECT_GT(desc->rtp_header_extensions().size(), 0u); 438 } 439 440 void CreateOfferAsRemoteDescription() { 441 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 442 EXPECT_TRUE(DoCreateOffer(offer.use())); 443 std::string sdp; 444 EXPECT_TRUE(offer->ToString(&sdp)); 445 SessionDescriptionInterface* remote_offer = 446 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 447 sdp, NULL); 448 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); 449 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); 450 } 451 452 void CreateAnswerAsLocalDescription() { 453 scoped_ptr<SessionDescriptionInterface> answer; 454 EXPECT_TRUE(DoCreateAnswer(answer.use())); 455 456 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 457 // audio codec change, even if the parameter has nothing to do with 458 // receiving. Not all parameters are serialized to SDP. 459 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 460 // the SessionDescription, it is necessary to do that here to in order to 461 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 462 // https://code.google.com/p/webrtc/issues/detail?id=1356 463 std::string sdp; 464 EXPECT_TRUE(answer->ToString(&sdp)); 465 SessionDescriptionInterface* new_answer = 466 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 467 sdp, NULL); 468 EXPECT_TRUE(DoSetLocalDescription(new_answer)); 469 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 470 } 471 472 void CreatePrAnswerAsLocalDescription() { 473 scoped_ptr<SessionDescriptionInterface> answer; 474 EXPECT_TRUE(DoCreateAnswer(answer.use())); 475 476 std::string sdp; 477 EXPECT_TRUE(answer->ToString(&sdp)); 478 SessionDescriptionInterface* pr_answer = 479 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer, 480 sdp, NULL); 481 EXPECT_TRUE(DoSetLocalDescription(pr_answer)); 482 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_); 483 } 484 485 void CreateOfferReceiveAnswer() { 486 CreateOfferAsLocalDescription(); 487 std::string sdp; 488 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 489 CreateAnswerAsRemoteDescription(sdp); 490 } 491 492 void CreateOfferAsLocalDescription() { 493 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 494 ASSERT_TRUE(DoCreateOffer(offer.use())); 495 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an 496 // audio codec change, even if the parameter has nothing to do with 497 // receiving. Not all parameters are serialized to SDP. 498 // Since CreatePrAnswerAsLocalDescription serialize/deserialize 499 // the SessionDescription, it is necessary to do that here to in order to 500 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. 501 // https://code.google.com/p/webrtc/issues/detail?id=1356 502 std::string sdp; 503 EXPECT_TRUE(offer->ToString(&sdp)); 504 SessionDescriptionInterface* new_offer = 505 webrtc::CreateSessionDescription( 506 SessionDescriptionInterface::kOffer, 507 sdp, NULL); 508 509 EXPECT_TRUE(DoSetLocalDescription(new_offer)); 510 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_); 511 // Wait for the ice_complete message, so that SDP will have candidates. 512 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); 513 } 514 515 void CreateAnswerAsRemoteDescription(const std::string& offer) { 516 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 517 SessionDescriptionInterface::kAnswer); 518 EXPECT_TRUE(answer->Initialize(offer, NULL)); 519 EXPECT_TRUE(DoSetRemoteDescription(answer)); 520 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 521 } 522 523 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& offer) { 524 webrtc::JsepSessionDescription* pr_answer = 525 new webrtc::JsepSessionDescription( 526 SessionDescriptionInterface::kPrAnswer); 527 EXPECT_TRUE(pr_answer->Initialize(offer, NULL)); 528 EXPECT_TRUE(DoSetRemoteDescription(pr_answer)); 529 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_); 530 webrtc::JsepSessionDescription* answer = 531 new webrtc::JsepSessionDescription( 532 SessionDescriptionInterface::kAnswer); 533 EXPECT_TRUE(answer->Initialize(offer, NULL)); 534 EXPECT_TRUE(DoSetRemoteDescription(answer)); 535 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); 536 } 537 538 // Help function used for waiting until a the last signaled remote stream has 539 // the same label as |stream_label|. In a few of the tests in this file we 540 // answer with the same session description as we offer and thus we can 541 // check if OnAddStream have been called with the same stream as we offer to 542 // send. 543 void WaitAndVerifyOnAddStream(const std::string& stream_label) { 544 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout); 545 } 546 547 // Creates an offer and applies it as a local session description. 548 // Creates an answer with the same SDP an the offer but removes all lines 549 // that start with a:ssrc" 550 void CreateOfferReceiveAnswerWithoutSsrc() { 551 CreateOfferAsLocalDescription(); 552 std::string sdp; 553 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 554 SetSsrcToZero(&sdp); 555 CreateAnswerAsRemoteDescription(sdp); 556 } 557 558 scoped_refptr<FakePortAllocatorFactory> port_allocator_factory_; 559 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; 560 scoped_refptr<PeerConnectionInterface> pc_; 561 MockPeerConnectionObserver observer_; 562}; 563 564TEST_F(PeerConnectionInterfaceTest, 565 CreatePeerConnectionWithDifferentConfigurations) { 566 CreatePeerConnectionWithDifferentConfigurations(); 567} 568 569TEST_F(PeerConnectionInterfaceTest, AddStreams) { 570 CreatePeerConnection(); 571 AddStream(kStreamLabel1); 572 AddVoiceStream(kStreamLabel2); 573 ASSERT_EQ(2u, pc_->local_streams()->count()); 574 575 // Test we can add multiple local streams to one peerconnection. 576 scoped_refptr<MediaStreamInterface> stream( 577 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); 578 scoped_refptr<AudioTrackInterface> audio_track( 579 pc_factory_->CreateAudioTrack( 580 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); 581 stream->AddTrack(audio_track.get()); 582 EXPECT_TRUE(pc_->AddStream(stream, NULL)); 583 EXPECT_EQ(3u, pc_->local_streams()->count()); 584 585 // Remove the third stream. 586 pc_->RemoveStream(pc_->local_streams()->at(2)); 587 EXPECT_EQ(2u, pc_->local_streams()->count()); 588 589 // Remove the second stream. 590 pc_->RemoveStream(pc_->local_streams()->at(1)); 591 EXPECT_EQ(1u, pc_->local_streams()->count()); 592 593 // Remove the first stream. 594 pc_->RemoveStream(pc_->local_streams()->at(0)); 595 EXPECT_EQ(0u, pc_->local_streams()->count()); 596} 597 598TEST_F(PeerConnectionInterfaceTest, RemoveStream) { 599 CreatePeerConnection(); 600 AddStream(kStreamLabel1); 601 ASSERT_EQ(1u, pc_->local_streams()->count()); 602 pc_->RemoveStream(pc_->local_streams()->at(0)); 603 EXPECT_EQ(0u, pc_->local_streams()->count()); 604} 605 606TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) { 607 InitiateCall(); 608 WaitAndVerifyOnAddStream(kStreamLabel1); 609 VerifyRemoteRtpHeaderExtensions(); 610} 611 612TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) { 613 CreatePeerConnection(); 614 AddStream(kStreamLabel1); 615 CreateOfferAsLocalDescription(); 616 std::string offer; 617 EXPECT_TRUE(pc_->local_description()->ToString(&offer)); 618 CreatePrAnswerAndAnswerAsRemoteDescription(offer); 619 WaitAndVerifyOnAddStream(kStreamLabel1); 620} 621 622TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) { 623 CreatePeerConnection(); 624 AddStream(kStreamLabel1); 625 626 CreateOfferAsRemoteDescription(); 627 CreateAnswerAsLocalDescription(); 628 629 WaitAndVerifyOnAddStream(kStreamLabel1); 630} 631 632TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) { 633 CreatePeerConnection(); 634 AddStream(kStreamLabel1); 635 636 CreateOfferAsRemoteDescription(); 637 CreatePrAnswerAsLocalDescription(); 638 CreateAnswerAsLocalDescription(); 639 640 WaitAndVerifyOnAddStream(kStreamLabel1); 641} 642 643TEST_F(PeerConnectionInterfaceTest, Renegotiate) { 644 InitiateCall(); 645 ASSERT_EQ(1u, pc_->remote_streams()->count()); 646 pc_->RemoveStream(pc_->local_streams()->at(0)); 647 CreateOfferReceiveAnswer(); 648 EXPECT_EQ(0u, pc_->remote_streams()->count()); 649 AddStream(kStreamLabel1); 650 CreateOfferReceiveAnswer(); 651} 652 653// Tests that after negotiating an audio only call, the respondent can perform a 654// renegotiation that removes the audio stream. 655TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) { 656 CreatePeerConnection(); 657 AddVoiceStream(kStreamLabel1); 658 CreateOfferAsRemoteDescription(); 659 CreateAnswerAsLocalDescription(); 660 661 ASSERT_EQ(1u, pc_->remote_streams()->count()); 662 pc_->RemoveStream(pc_->local_streams()->at(0)); 663 CreateOfferReceiveAnswer(); 664 EXPECT_EQ(0u, pc_->remote_streams()->count()); 665} 666 667// Test that candidates are generated and that we can parse our own candidates. 668TEST_F(PeerConnectionInterfaceTest, IceCandidates) { 669 CreatePeerConnection(); 670 671 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 672 // SetRemoteDescription takes ownership of offer. 673 SessionDescriptionInterface* offer = NULL; 674 AddStream(kStreamLabel1); 675 EXPECT_TRUE(DoCreateOffer(&offer)); 676 EXPECT_TRUE(DoSetRemoteDescription(offer)); 677 678 // SetLocalDescription takes ownership of answer. 679 SessionDescriptionInterface* answer = NULL; 680 EXPECT_TRUE(DoCreateAnswer(&answer)); 681 EXPECT_TRUE(DoSetLocalDescription(answer)); 682 683 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); 684 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); 685 686 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get())); 687} 688 689// Test that the CreateOffer and CreatAnswer will fail if the track labels are 690// not unique. 691TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { 692 CreatePeerConnection(); 693 // Create a regular offer for the CreateAnswer test later. 694 SessionDescriptionInterface* offer = NULL; 695 EXPECT_TRUE(DoCreateOffer(&offer)); 696 EXPECT_TRUE(offer != NULL); 697 delete offer; 698 offer = NULL; 699 700 // Create a local stream with audio&video tracks having same label. 701 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label"); 702 703 // Test CreateOffer 704 EXPECT_FALSE(DoCreateOffer(&offer)); 705 706 // Test CreateAnswer 707 SessionDescriptionInterface* answer = NULL; 708 EXPECT_FALSE(DoCreateAnswer(&answer)); 709} 710 711// Test that we will get different SSRCs for each tracks in the offer and answer 712// we created. 713TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) { 714 CreatePeerConnection(); 715 // Create a local stream with audio&video tracks having different labels. 716 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 717 718 // Test CreateOffer 719 scoped_ptr<SessionDescriptionInterface> offer; 720 EXPECT_TRUE(DoCreateOffer(offer.use())); 721 int audio_ssrc = 0; 722 int video_ssrc = 0; 723 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()), 724 &audio_ssrc)); 725 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()), 726 &video_ssrc)); 727 EXPECT_NE(audio_ssrc, video_ssrc); 728 729 // Test CreateAnswer 730 EXPECT_TRUE(DoSetRemoteDescription(offer.release())); 731 scoped_ptr<SessionDescriptionInterface> answer; 732 EXPECT_TRUE(DoCreateAnswer(answer.use())); 733 audio_ssrc = 0; 734 video_ssrc = 0; 735 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()), 736 &audio_ssrc)); 737 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()), 738 &video_ssrc)); 739 EXPECT_NE(audio_ssrc, video_ssrc); 740} 741 742// Test that we can specify a certain track that we want statistics about. 743TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) { 744 InitiateCall(); 745 ASSERT_LT(0u, pc_->remote_streams()->count()); 746 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size()); 747 scoped_refptr<MediaStreamTrackInterface> remote_audio = 748 pc_->remote_streams()->at(0)->GetAudioTracks()[0]; 749 EXPECT_TRUE(DoGetStats(remote_audio)); 750 751 // Remove the stream. Since we are sending to our selves the local 752 // and the remote stream is the same. 753 pc_->RemoveStream(pc_->local_streams()->at(0)); 754 // Do a re-negotiation. 755 CreateOfferReceiveAnswer(); 756 757 ASSERT_EQ(0u, pc_->remote_streams()->count()); 758 759 // Test that we still can get statistics for the old track. Even if it is not 760 // sent any longer. 761 EXPECT_TRUE(DoGetStats(remote_audio)); 762} 763 764// Test that we can get stats on a video track. 765TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) { 766 InitiateCall(); 767 ASSERT_LT(0u, pc_->remote_streams()->count()); 768 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size()); 769 scoped_refptr<MediaStreamTrackInterface> remote_video = 770 pc_->remote_streams()->at(0)->GetVideoTracks()[0]; 771 EXPECT_TRUE(DoGetStats(remote_video)); 772} 773 774// Test that we don't get statistics for an invalid track. 775TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) { 776 InitiateCall(); 777 scoped_refptr<AudioTrackInterface> unknown_audio_track( 778 pc_factory_->CreateAudioTrack("unknown track", NULL)); 779 EXPECT_FALSE(DoGetStats(unknown_audio_track)); 780} 781 782// This test setup two RTP data channels in loop back. 783TEST_F(PeerConnectionInterfaceTest, TestDataChannel) { 784 FakeConstraints constraints; 785 constraints.SetAllowRtpDataChannels(); 786 CreatePeerConnection(&constraints); 787 scoped_refptr<DataChannelInterface> data1 = 788 pc_->CreateDataChannel("test1", NULL); 789 scoped_refptr<DataChannelInterface> data2 = 790 pc_->CreateDataChannel("test2", NULL); 791 ASSERT_TRUE(data1 != NULL); 792 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 793 new MockDataChannelObserver(data1)); 794 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 795 new MockDataChannelObserver(data2)); 796 797 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 798 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 799 std::string data_to_send1 = "testing testing"; 800 std::string data_to_send2 = "testing something else"; 801 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1))); 802 803 CreateOfferReceiveAnswer(); 804 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 805 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 806 807 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 808 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 809 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1))); 810 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 811 812 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout); 813 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 814 815 data1->Close(); 816 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 817 CreateOfferReceiveAnswer(); 818 EXPECT_FALSE(observer1->IsOpen()); 819 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 820 EXPECT_TRUE(observer2->IsOpen()); 821 822 data_to_send2 = "testing something else again"; 823 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2))); 824 825 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout); 826} 827 828// This test verifies that sendnig binary data over RTP data channels should 829// fail. 830TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { 831 FakeConstraints constraints; 832 constraints.SetAllowRtpDataChannels(); 833 CreatePeerConnection(&constraints); 834 scoped_refptr<DataChannelInterface> data1 = 835 pc_->CreateDataChannel("test1", NULL); 836 scoped_refptr<DataChannelInterface> data2 = 837 pc_->CreateDataChannel("test2", NULL); 838 ASSERT_TRUE(data1 != NULL); 839 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 840 new MockDataChannelObserver(data1)); 841 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 842 new MockDataChannelObserver(data2)); 843 844 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state()); 845 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state()); 846 847 CreateOfferReceiveAnswer(); 848 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 849 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 850 851 EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); 852 EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); 853 854 talk_base::Buffer buffer("test", 4); 855 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); 856} 857 858// This test setup a RTP data channels in loop back and test that a channel is 859// opened even if the remote end answer with a zero SSRC. 860TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) { 861 FakeConstraints constraints; 862 constraints.SetAllowRtpDataChannels(); 863 CreatePeerConnection(&constraints); 864 scoped_refptr<DataChannelInterface> data1 = 865 pc_->CreateDataChannel("test1", NULL); 866 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 867 new MockDataChannelObserver(data1)); 868 869 CreateOfferReceiveAnswerWithoutSsrc(); 870 871 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 872 873 data1->Close(); 874 EXPECT_EQ(DataChannelInterface::kClosing, data1->state()); 875 CreateOfferReceiveAnswerWithoutSsrc(); 876 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 877 EXPECT_FALSE(observer1->IsOpen()); 878} 879 880// This test that if a data channel is added in an answer a receive only channel 881// channel is created. 882TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) { 883 FakeConstraints constraints; 884 constraints.SetAllowRtpDataChannels(); 885 CreatePeerConnection(&constraints); 886 887 std::string offer_label = "offer_channel"; 888 scoped_refptr<DataChannelInterface> offer_channel = 889 pc_->CreateDataChannel(offer_label, NULL); 890 891 CreateOfferAsLocalDescription(); 892 893 // Replace the data channel label in the offer and apply it as an answer. 894 std::string receive_label = "answer_channel"; 895 std::string sdp; 896 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 897 talk_base::replace_substrs(offer_label.c_str(), offer_label.length(), 898 receive_label.c_str(), receive_label.length(), 899 &sdp); 900 CreateAnswerAsRemoteDescription(sdp); 901 902 // Verify that a new incoming data channel has been created and that 903 // it is open but can't we written to. 904 ASSERT_TRUE(observer_.last_datachannel_ != NULL); 905 DataChannelInterface* received_channel = observer_.last_datachannel_; 906 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state()); 907 EXPECT_EQ(receive_label, received_channel->label()); 908 EXPECT_FALSE(received_channel->Send(DataBuffer("something"))); 909 910 // Verify that the channel we initially offered has been rejected. 911 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 912 913 // Do another offer / answer exchange and verify that the data channel is 914 // opened. 915 CreateOfferReceiveAnswer(); 916 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(), 917 kTimeout); 918} 919 920// This test that no data channel is returned if a reliable channel is 921// requested. 922// TODO(perkj): Remove this test once reliable channels are implemented. 923TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) { 924 FakeConstraints constraints; 925 constraints.SetAllowRtpDataChannels(); 926 CreatePeerConnection(&constraints); 927 928 std::string label = "test"; 929 webrtc::DataChannelInit config; 930 config.reliable = true; 931 scoped_refptr<DataChannelInterface> channel = 932 pc_->CreateDataChannel(label, &config); 933 EXPECT_TRUE(channel == NULL); 934} 935 936// This tests that a SCTP data channel is returned using different 937// DataChannelInit configurations. 938TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { 939 FakeConstraints constraints; 940 constraints.SetAllowDtlsSctpDataChannels(); 941 CreatePeerConnection(&constraints); 942 943 webrtc::DataChannelInit config; 944 945 scoped_refptr<DataChannelInterface> channel = 946 pc_->CreateDataChannel("1", &config); 947 EXPECT_TRUE(channel != NULL); 948 EXPECT_TRUE(channel->reliable()); 949 EXPECT_TRUE(observer_.renegotiation_needed_); 950 observer_.renegotiation_needed_ = false; 951 952 config.ordered = false; 953 channel = pc_->CreateDataChannel("2", &config); 954 EXPECT_TRUE(channel != NULL); 955 EXPECT_TRUE(channel->reliable()); 956 EXPECT_FALSE(observer_.renegotiation_needed_); 957 958 config.ordered = true; 959 config.maxRetransmits = 0; 960 channel = pc_->CreateDataChannel("3", &config); 961 EXPECT_TRUE(channel != NULL); 962 EXPECT_FALSE(channel->reliable()); 963 EXPECT_FALSE(observer_.renegotiation_needed_); 964 965 config.maxRetransmits = -1; 966 config.maxRetransmitTime = 0; 967 channel = pc_->CreateDataChannel("4", &config); 968 EXPECT_TRUE(channel != NULL); 969 EXPECT_FALSE(channel->reliable()); 970 EXPECT_FALSE(observer_.renegotiation_needed_); 971} 972 973// This tests that no data channel is returned if both maxRetransmits and 974// maxRetransmitTime are set for SCTP data channels. 975TEST_F(PeerConnectionInterfaceTest, 976 CreateSctpDataChannelShouldFailForInvalidConfig) { 977 FakeConstraints constraints; 978 constraints.SetAllowDtlsSctpDataChannels(); 979 CreatePeerConnection(&constraints); 980 981 std::string label = "test"; 982 webrtc::DataChannelInit config; 983 config.maxRetransmits = 0; 984 config.maxRetransmitTime = 0; 985 986 scoped_refptr<DataChannelInterface> channel = 987 pc_->CreateDataChannel(label, &config); 988 EXPECT_TRUE(channel == NULL); 989} 990 991// The test verifies that creating a SCTP data channel with an id already in use 992// or out of range should fail. 993TEST_F(PeerConnectionInterfaceTest, 994 CreateSctpDataChannelWithInvalidIdShouldFail) { 995 FakeConstraints constraints; 996 constraints.SetAllowDtlsSctpDataChannels(); 997 CreatePeerConnection(&constraints); 998 999 webrtc::DataChannelInit config; 1000 scoped_refptr<DataChannelInterface> channel; 1001 1002 config.id = 1; 1003 channel = pc_->CreateDataChannel("1", &config); 1004 EXPECT_TRUE(channel != NULL); 1005 EXPECT_EQ(1, channel->id()); 1006 1007 channel = pc_->CreateDataChannel("x", &config); 1008 EXPECT_TRUE(channel == NULL); 1009 1010 config.id = cricket::kMaxSctpSid; 1011 channel = pc_->CreateDataChannel("max", &config); 1012 EXPECT_TRUE(channel != NULL); 1013 EXPECT_EQ(config.id, channel->id()); 1014 1015 config.id = cricket::kMaxSctpSid + 1; 1016 channel = pc_->CreateDataChannel("x", &config); 1017 EXPECT_TRUE(channel == NULL); 1018} 1019 1020// This test verifies that OnRenegotiationNeeded is fired for every new RTP 1021// DataChannel. 1022TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { 1023 FakeConstraints constraints; 1024 constraints.SetAllowRtpDataChannels(); 1025 CreatePeerConnection(&constraints); 1026 1027 scoped_refptr<DataChannelInterface> dc1 = 1028 pc_->CreateDataChannel("test1", NULL); 1029 EXPECT_TRUE(observer_.renegotiation_needed_); 1030 observer_.renegotiation_needed_ = false; 1031 1032 scoped_refptr<DataChannelInterface> dc2 = 1033 pc_->CreateDataChannel("test2", NULL); 1034 EXPECT_TRUE(observer_.renegotiation_needed_); 1035} 1036 1037// This test that a data channel closes when a PeerConnection is deleted/closed. 1038TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) { 1039 FakeConstraints constraints; 1040 constraints.SetAllowRtpDataChannels(); 1041 CreatePeerConnection(&constraints); 1042 1043 scoped_refptr<DataChannelInterface> data1 = 1044 pc_->CreateDataChannel("test1", NULL); 1045 scoped_refptr<DataChannelInterface> data2 = 1046 pc_->CreateDataChannel("test2", NULL); 1047 ASSERT_TRUE(data1 != NULL); 1048 talk_base::scoped_ptr<MockDataChannelObserver> observer1( 1049 new MockDataChannelObserver(data1)); 1050 talk_base::scoped_ptr<MockDataChannelObserver> observer2( 1051 new MockDataChannelObserver(data2)); 1052 1053 CreateOfferReceiveAnswer(); 1054 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout); 1055 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout); 1056 1057 ReleasePeerConnection(); 1058 EXPECT_EQ(DataChannelInterface::kClosed, data1->state()); 1059 EXPECT_EQ(DataChannelInterface::kClosed, data2->state()); 1060} 1061 1062// This test that data channels can be rejected in an answer. 1063TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) { 1064 FakeConstraints constraints; 1065 constraints.SetAllowRtpDataChannels(); 1066 CreatePeerConnection(&constraints); 1067 1068 scoped_refptr<DataChannelInterface> offer_channel( 1069 pc_->CreateDataChannel("offer_channel", NULL)); 1070 1071 CreateOfferAsLocalDescription(); 1072 1073 // Create an answer where the m-line for data channels are rejected. 1074 std::string sdp; 1075 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); 1076 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( 1077 SessionDescriptionInterface::kAnswer); 1078 EXPECT_TRUE(answer->Initialize(sdp, NULL)); 1079 cricket::ContentInfo* data_info = 1080 answer->description()->GetContentByName("data"); 1081 data_info->rejected = true; 1082 1083 DoSetRemoteDescription(answer); 1084 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state()); 1085} 1086 1087// Test that we can create a session description from an SDP string from 1088// FireFox, use it as a remote session description, generate an answer and use 1089// the answer as a local description. 1090TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) { 1091 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp); 1092 FakeConstraints constraints; 1093 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, 1094 true); 1095 CreatePeerConnection(&constraints); 1096 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1097 SessionDescriptionInterface* desc = 1098 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1099 webrtc::kFireFoxSdpOffer); 1100 EXPECT_TRUE(DoSetSessionDescription(desc, false)); 1101 CreateAnswerAsLocalDescription(); 1102 ASSERT_TRUE(pc_->local_description() != NULL); 1103 ASSERT_TRUE(pc_->remote_description() != NULL); 1104 1105 const cricket::ContentInfo* content = 1106 cricket::GetFirstAudioContent(pc_->local_description()->description()); 1107 ASSERT_TRUE(content != NULL); 1108 EXPECT_FALSE(content->rejected); 1109 1110 content = 1111 cricket::GetFirstVideoContent(pc_->local_description()->description()); 1112 ASSERT_TRUE(content != NULL); 1113 EXPECT_FALSE(content->rejected); 1114#ifdef HAVE_SCTP 1115 content = 1116 cricket::GetFirstDataContent(pc_->local_description()->description()); 1117 ASSERT_TRUE(content != NULL); 1118 EXPECT_TRUE(content->rejected); 1119#endif 1120} 1121 1122// Test that we can create an audio only offer and receive an answer with a 1123// limited set of audio codecs and receive an updated offer with more audio 1124// codecs, where the added codecs are not supported. 1125TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) { 1126 CreatePeerConnection(); 1127 AddVoiceStream("audio_label"); 1128 CreateOfferAsLocalDescription(); 1129 1130 SessionDescriptionInterface* answer = 1131 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, 1132 webrtc::kAudioSdp); 1133 EXPECT_TRUE(DoSetSessionDescription(answer, false)); 1134 1135 SessionDescriptionInterface* updated_offer = 1136 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1137 webrtc::kAudioSdpWithUnsupportedCodecs); 1138 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false)); 1139 CreateAnswerAsLocalDescription(); 1140} 1141 1142// Test that PeerConnection::Close changes the states to closed and all remote 1143// tracks change state to ended. 1144TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) { 1145 // Initialize a PeerConnection and negotiate local and remote session 1146 // description. 1147 InitiateCall(); 1148 ASSERT_EQ(1u, pc_->local_streams()->count()); 1149 ASSERT_EQ(1u, pc_->remote_streams()->count()); 1150 1151 pc_->Close(); 1152 1153 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state()); 1154 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed, 1155 pc_->ice_connection_state()); 1156 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete, 1157 pc_->ice_gathering_state()); 1158 1159 EXPECT_EQ(1u, pc_->local_streams()->count()); 1160 EXPECT_EQ(1u, pc_->remote_streams()->count()); 1161 1162 scoped_refptr<MediaStreamInterface> remote_stream = 1163 pc_->remote_streams()->at(0); 1164 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1165 remote_stream->GetVideoTracks()[0]->state()); 1166 EXPECT_EQ(MediaStreamTrackInterface::kEnded, 1167 remote_stream->GetAudioTracks()[0]->state()); 1168} 1169 1170// Test that PeerConnection methods fails gracefully after 1171// PeerConnection::Close has been called. 1172TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) { 1173 CreatePeerConnection(); 1174 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label"); 1175 CreateOfferAsRemoteDescription(); 1176 CreateAnswerAsLocalDescription(); 1177 1178 ASSERT_EQ(1u, pc_->local_streams()->count()); 1179 scoped_refptr<MediaStreamInterface> local_stream = 1180 pc_->local_streams()->at(0); 1181 1182 pc_->Close(); 1183 1184 pc_->RemoveStream(local_stream); 1185 EXPECT_FALSE(pc_->AddStream(local_stream, NULL)); 1186 1187 ASSERT_FALSE(local_stream->GetAudioTracks().empty()); 1188 talk_base::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender( 1189 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0])); 1190 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed. 1191 1192 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL); 1193 1194 EXPECT_TRUE(pc_->local_description() != NULL); 1195 EXPECT_TRUE(pc_->remote_description() != NULL); 1196 1197 talk_base::scoped_ptr<SessionDescriptionInterface> offer; 1198 EXPECT_TRUE(DoCreateOffer(offer.use())); 1199 talk_base::scoped_ptr<SessionDescriptionInterface> answer; 1200 EXPECT_TRUE(DoCreateAnswer(answer.use())); 1201 1202 std::string sdp; 1203 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp)); 1204 SessionDescriptionInterface* remote_offer = 1205 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1206 sdp, NULL); 1207 EXPECT_FALSE(DoSetRemoteDescription(remote_offer)); 1208 1209 ASSERT_TRUE(pc_->local_description()->ToString(&sdp)); 1210 SessionDescriptionInterface* local_offer = 1211 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, 1212 sdp, NULL); 1213 EXPECT_FALSE(DoSetLocalDescription(local_offer)); 1214} 1215 1216// Test that GetStats can still be called after PeerConnection::Close. 1217TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) { 1218 InitiateCall(); 1219 pc_->Close(); 1220 DoGetStats(NULL); 1221} 1222