1 /* 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <map> 12 13 #include "webrtc/base/fakesslidentity.h" 14 #include "webrtc/base/gunit.h" 15 #include "webrtc/base/helpers.h" 16 #include "webrtc/base/scoped_ptr.h" 17 #include "webrtc/base/sslidentity.h" 18 #include "webrtc/base/thread.h" 19 #include "webrtc/p2p/base/dtlstransportchannel.h" 20 #include "webrtc/p2p/base/faketransportcontroller.h" 21 #include "webrtc/p2p/base/p2ptransportchannel.h" 22 #include "webrtc/p2p/base/portallocator.h" 23 #include "webrtc/p2p/base/transportcontroller.h" 24 #include "webrtc/p2p/client/fakeportallocator.h" 25 26 static const int kTimeout = 100; 27 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; 28 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; 29 static const char kIceUfrag2[] = "TESTICEUFRAG0002"; 30 static const char kIcePwd2[] = "TESTICEPWD00000000000002"; 31 32 using cricket::Candidate; 33 using cricket::Candidates; 34 using cricket::FakeTransportChannel; 35 using cricket::FakeTransportController; 36 using cricket::IceConnectionState; 37 using cricket::IceGatheringState; 38 using cricket::TransportChannel; 39 using cricket::TransportController; 40 using cricket::TransportDescription; 41 using cricket::TransportStats; 42 43 // Only subclassing from FakeTransportController because currently that's the 44 // only way to have a TransportController with fake TransportChannels. 45 // 46 // TODO(deadbeef): Change this once the Transport/TransportChannel class 47 // heirarchy is cleaned up, and we can pass a "TransportChannelFactory" or 48 // something similar into TransportController. 49 typedef FakeTransportController TransportControllerForTest; 50 51 class TransportControllerTest : public testing::Test, 52 public sigslot::has_slots<> { 53 public: 54 TransportControllerTest() 55 : transport_controller_(new TransportControllerForTest()), 56 signaling_thread_(rtc::Thread::Current()) { 57 ConnectTransportControllerSignals(); 58 } 59 60 void CreateTransportControllerWithWorkerThread() { 61 if (!worker_thread_) { 62 worker_thread_.reset(new rtc::Thread()); 63 worker_thread_->Start(); 64 } 65 transport_controller_.reset( 66 new TransportControllerForTest(worker_thread_.get())); 67 ConnectTransportControllerSignals(); 68 } 69 70 void ConnectTransportControllerSignals() { 71 transport_controller_->SignalConnectionState.connect( 72 this, &TransportControllerTest::OnConnectionState); 73 transport_controller_->SignalReceiving.connect( 74 this, &TransportControllerTest::OnReceiving); 75 transport_controller_->SignalGatheringState.connect( 76 this, &TransportControllerTest::OnGatheringState); 77 transport_controller_->SignalCandidatesGathered.connect( 78 this, &TransportControllerTest::OnCandidatesGathered); 79 } 80 81 FakeTransportChannel* CreateChannel(const std::string& content, 82 int component) { 83 TransportChannel* channel = 84 transport_controller_->CreateTransportChannel_w(content, component); 85 return static_cast<FakeTransportChannel*>(channel); 86 } 87 88 void DestroyChannel(const std::string& content, int component) { 89 transport_controller_->DestroyTransportChannel_w(content, component); 90 } 91 92 Candidate CreateCandidate(int component) { 93 Candidate c; 94 c.set_address(rtc::SocketAddress("192.168.1.1", 8000)); 95 c.set_component(1); 96 c.set_protocol(cricket::UDP_PROTOCOL_NAME); 97 c.set_priority(1); 98 return c; 99 } 100 101 // Used for thread hopping test. 102 void CreateChannelsAndCompleteConnectionOnWorkerThread() { 103 worker_thread_->Invoke<void>(rtc::Bind( 104 &TransportControllerTest::CreateChannelsAndCompleteConnection_w, this)); 105 } 106 107 void CreateChannelsAndCompleteConnection_w() { 108 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 109 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 110 ASSERT_NE(nullptr, channel1); 111 FakeTransportChannel* channel2 = CreateChannel("video", 1); 112 ASSERT_NE(nullptr, channel2); 113 114 TransportDescription local_desc( 115 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, 116 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 117 std::string err; 118 transport_controller_->SetLocalTransportDescription( 119 "audio", local_desc, cricket::CA_OFFER, &err); 120 transport_controller_->SetLocalTransportDescription( 121 "video", local_desc, cricket::CA_OFFER, &err); 122 transport_controller_->MaybeStartGathering(); 123 channel1->SignalCandidateGathered(channel1, CreateCandidate(1)); 124 channel2->SignalCandidateGathered(channel2, CreateCandidate(1)); 125 channel1->SetCandidatesGatheringComplete(); 126 channel2->SetCandidatesGatheringComplete(); 127 channel1->SetConnectionCount(2); 128 channel2->SetConnectionCount(2); 129 channel1->SetReceiving(true); 130 channel2->SetReceiving(true); 131 channel1->SetWritable(true); 132 channel2->SetWritable(true); 133 channel1->SetConnectionCount(1); 134 channel2->SetConnectionCount(1); 135 } 136 137 cricket::IceConfig CreateIceConfig(int receiving_timeout_ms, 138 bool gather_continually) { 139 cricket::IceConfig config; 140 config.receiving_timeout_ms = receiving_timeout_ms; 141 config.gather_continually = gather_continually; 142 return config; 143 } 144 145 protected: 146 void OnConnectionState(IceConnectionState state) { 147 if (!signaling_thread_->IsCurrent()) { 148 signaled_on_non_signaling_thread_ = true; 149 } 150 connection_state_ = state; 151 ++connection_state_signal_count_; 152 } 153 154 void OnReceiving(bool receiving) { 155 if (!signaling_thread_->IsCurrent()) { 156 signaled_on_non_signaling_thread_ = true; 157 } 158 receiving_ = receiving; 159 ++receiving_signal_count_; 160 } 161 162 void OnGatheringState(IceGatheringState state) { 163 if (!signaling_thread_->IsCurrent()) { 164 signaled_on_non_signaling_thread_ = true; 165 } 166 gathering_state_ = state; 167 ++gathering_state_signal_count_; 168 } 169 170 void OnCandidatesGathered(const std::string& transport_name, 171 const Candidates& candidates) { 172 if (!signaling_thread_->IsCurrent()) { 173 signaled_on_non_signaling_thread_ = true; 174 } 175 candidates_[transport_name].insert(candidates_[transport_name].end(), 176 candidates.begin(), candidates.end()); 177 ++candidates_signal_count_; 178 } 179 180 rtc::scoped_ptr<rtc::Thread> worker_thread_; // Not used for most tests. 181 rtc::scoped_ptr<TransportControllerForTest> transport_controller_; 182 183 // Information received from signals from transport controller. 184 IceConnectionState connection_state_ = cricket::kIceConnectionConnecting; 185 bool receiving_ = false; 186 IceGatheringState gathering_state_ = cricket::kIceGatheringNew; 187 // transport_name => candidates 188 std::map<std::string, Candidates> candidates_; 189 // Counts of each signal emitted. 190 int connection_state_signal_count_ = 0; 191 int receiving_signal_count_ = 0; 192 int gathering_state_signal_count_ = 0; 193 int candidates_signal_count_ = 0; 194 195 // Used to make sure signals only come on signaling thread. 196 rtc::Thread* const signaling_thread_ = nullptr; 197 bool signaled_on_non_signaling_thread_ = false; 198 }; 199 200 TEST_F(TransportControllerTest, TestSetIceConfig) { 201 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 202 ASSERT_NE(nullptr, channel1); 203 204 transport_controller_->SetIceConfig(CreateIceConfig(1000, true)); 205 EXPECT_EQ(1000, channel1->receiving_timeout()); 206 EXPECT_TRUE(channel1->gather_continually()); 207 208 // Test that value stored in controller is applied to new channels. 209 FakeTransportChannel* channel2 = CreateChannel("video", 1); 210 ASSERT_NE(nullptr, channel2); 211 EXPECT_EQ(1000, channel2->receiving_timeout()); 212 EXPECT_TRUE(channel2->gather_continually()); 213 } 214 215 TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) { 216 EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion( 217 rtc::SSL_PROTOCOL_DTLS_12)); 218 FakeTransportChannel* channel = CreateChannel("audio", 1); 219 220 ASSERT_NE(nullptr, channel); 221 EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, channel->ssl_max_protocol_version()); 222 223 // Setting max version after transport is created should fail. 224 EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion( 225 rtc::SSL_PROTOCOL_DTLS_10)); 226 } 227 228 TEST_F(TransportControllerTest, TestSetIceRole) { 229 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 230 ASSERT_NE(nullptr, channel1); 231 232 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 233 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); 234 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); 235 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); 236 237 // Test that value stored in controller is applied to new channels. 238 FakeTransportChannel* channel2 = CreateChannel("video", 1); 239 ASSERT_NE(nullptr, channel2); 240 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole()); 241 } 242 243 // Test that when one channel encounters a role conflict, the ICE role is 244 // swapped on every channel. 245 TEST_F(TransportControllerTest, TestIceRoleConflict) { 246 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 247 ASSERT_NE(nullptr, channel1); 248 FakeTransportChannel* channel2 = CreateChannel("video", 1); 249 ASSERT_NE(nullptr, channel2); 250 251 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 252 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); 253 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole()); 254 255 channel1->SignalRoleConflict(channel1); 256 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); 257 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole()); 258 } 259 260 TEST_F(TransportControllerTest, TestGetSslRole) { 261 FakeTransportChannel* channel = CreateChannel("audio", 1); 262 ASSERT_NE(nullptr, channel); 263 ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT)); 264 rtc::SSLRole role; 265 EXPECT_FALSE(transport_controller_->GetSslRole("video", &role)); 266 EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role)); 267 EXPECT_EQ(rtc::SSL_CLIENT, role); 268 } 269 270 TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) { 271 rtc::scoped_refptr<rtc::RTCCertificate> certificate1 = 272 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( 273 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT))); 274 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 = 275 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( 276 rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT))); 277 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate; 278 279 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 280 ASSERT_NE(nullptr, channel1); 281 282 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1)); 283 EXPECT_TRUE(transport_controller_->GetLocalCertificate( 284 "audio", &returned_certificate)); 285 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), 286 returned_certificate->identity()->certificate().ToPEMString()); 287 288 // Should fail if called for a nonexistant transport. 289 EXPECT_FALSE(transport_controller_->GetLocalCertificate( 290 "video", &returned_certificate)); 291 292 // Test that identity stored in controller is applied to new channels. 293 FakeTransportChannel* channel2 = CreateChannel("video", 1); 294 ASSERT_NE(nullptr, channel2); 295 EXPECT_TRUE(transport_controller_->GetLocalCertificate( 296 "video", &returned_certificate)); 297 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), 298 returned_certificate->identity()->certificate().ToPEMString()); 299 300 // Shouldn't be able to change the identity once set. 301 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2)); 302 } 303 304 TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) { 305 rtc::FakeSSLCertificate fake_certificate("fake_data"); 306 rtc::scoped_ptr<rtc::SSLCertificate> returned_certificate; 307 308 FakeTransportChannel* channel = CreateChannel("audio", 1); 309 ASSERT_NE(nullptr, channel); 310 311 channel->SetRemoteSSLCertificate(&fake_certificate); 312 EXPECT_TRUE(transport_controller_->GetRemoteSSLCertificate( 313 "audio", returned_certificate.accept())); 314 EXPECT_EQ(fake_certificate.ToPEMString(), 315 returned_certificate->ToPEMString()); 316 317 // Should fail if called for a nonexistant transport. 318 EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate( 319 "video", returned_certificate.accept())); 320 } 321 322 TEST_F(TransportControllerTest, TestSetLocalTransportDescription) { 323 FakeTransportChannel* channel = CreateChannel("audio", 1); 324 ASSERT_NE(nullptr, channel); 325 TransportDescription local_desc( 326 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, 327 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 328 std::string err; 329 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( 330 "audio", local_desc, cricket::CA_OFFER, &err)); 331 // Check that ICE ufrag and pwd were propagated to channel. 332 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag()); 333 EXPECT_EQ(kIcePwd1, channel->ice_pwd()); 334 // After setting local description, we should be able to start gathering 335 // candidates. 336 transport_controller_->MaybeStartGathering(); 337 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); 338 EXPECT_EQ(1, gathering_state_signal_count_); 339 } 340 341 TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) { 342 FakeTransportChannel* channel = CreateChannel("audio", 1); 343 ASSERT_NE(nullptr, channel); 344 TransportDescription remote_desc( 345 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, 346 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 347 std::string err; 348 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( 349 "audio", remote_desc, cricket::CA_OFFER, &err)); 350 // Check that ICE ufrag and pwd were propagated to channel. 351 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag()); 352 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd()); 353 } 354 355 TEST_F(TransportControllerTest, TestAddRemoteCandidates) { 356 FakeTransportChannel* channel = CreateChannel("audio", 1); 357 ASSERT_NE(nullptr, channel); 358 Candidates candidates; 359 candidates.push_back(CreateCandidate(1)); 360 std::string err; 361 EXPECT_TRUE( 362 transport_controller_->AddRemoteCandidates("audio", candidates, &err)); 363 EXPECT_EQ(1U, channel->remote_candidates().size()); 364 } 365 366 TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) { 367 FakeTransportChannel* channel = CreateChannel("audio", 1); 368 ASSERT_NE(nullptr, channel); 369 // We expect to be ready for remote candidates only after local and remote 370 // descriptions are set. 371 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); 372 373 std::string err; 374 TransportDescription remote_desc( 375 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, 376 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 377 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( 378 "audio", remote_desc, cricket::CA_OFFER, &err)); 379 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); 380 381 TransportDescription local_desc( 382 std::vector<std::string>(), kIceUfrag2, kIcePwd2, cricket::ICEMODE_FULL, 383 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 384 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( 385 "audio", local_desc, cricket::CA_ANSWER, &err)); 386 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio")); 387 } 388 389 TEST_F(TransportControllerTest, TestGetStats) { 390 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 391 ASSERT_NE(nullptr, channel1); 392 FakeTransportChannel* channel2 = CreateChannel("audio", 2); 393 ASSERT_NE(nullptr, channel2); 394 FakeTransportChannel* channel3 = CreateChannel("video", 1); 395 ASSERT_NE(nullptr, channel3); 396 397 TransportStats stats; 398 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); 399 EXPECT_EQ("audio", stats.transport_name); 400 EXPECT_EQ(2U, stats.channel_stats.size()); 401 } 402 403 // Test that transport gets destroyed when it has no more channels. 404 TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) { 405 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 406 ASSERT_NE(nullptr, channel1); 407 FakeTransportChannel* channel2 = CreateChannel("audio", 1); 408 ASSERT_NE(nullptr, channel2); 409 ASSERT_EQ(channel1, channel2); 410 FakeTransportChannel* channel3 = CreateChannel("audio", 2); 411 ASSERT_NE(nullptr, channel3); 412 413 // Using GetStats to check if transport is destroyed from an outside class's 414 // perspective. 415 TransportStats stats; 416 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); 417 DestroyChannel("audio", 2); 418 DestroyChannel("audio", 1); 419 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); 420 DestroyChannel("audio", 1); 421 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats)); 422 } 423 424 TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) { 425 // Need controlling ICE role to get in failed state. 426 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 427 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 428 ASSERT_NE(nullptr, channel1); 429 FakeTransportChannel* channel2 = CreateChannel("video", 1); 430 ASSERT_NE(nullptr, channel2); 431 432 // Should signal "failed" if any channel failed; channel is considered failed 433 // if it previously had a connection but now has none, and gathering is 434 // complete. 435 channel1->SetCandidatesGatheringComplete(); 436 channel1->SetConnectionCount(1); 437 channel1->SetConnectionCount(0); 438 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); 439 EXPECT_EQ(1, connection_state_signal_count_); 440 } 441 442 TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) { 443 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 444 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 445 ASSERT_NE(nullptr, channel1); 446 FakeTransportChannel* channel2 = CreateChannel("video", 1); 447 ASSERT_NE(nullptr, channel2); 448 FakeTransportChannel* channel3 = CreateChannel("video", 2); 449 ASSERT_NE(nullptr, channel3); 450 451 // First, have one channel connect, and another fail, to ensure that 452 // the first channel connecting didn't trigger a "connected" state signal. 453 // We should only get a signal when all are connected. 454 channel1->SetConnectionCount(2); 455 channel1->SetWritable(true); 456 channel3->SetCandidatesGatheringComplete(); 457 channel3->SetConnectionCount(1); 458 channel3->SetConnectionCount(0); 459 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); 460 // Signal count of 1 means that the only signal emitted was "failed". 461 EXPECT_EQ(1, connection_state_signal_count_); 462 463 // Destroy the failed channel to return to "connecting" state. 464 DestroyChannel("video", 2); 465 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, 466 kTimeout); 467 EXPECT_EQ(2, connection_state_signal_count_); 468 469 // Make the remaining channel reach a connected state. 470 channel2->SetConnectionCount(2); 471 channel2->SetWritable(true); 472 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); 473 EXPECT_EQ(3, connection_state_signal_count_); 474 } 475 476 TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) { 477 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 478 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 479 ASSERT_NE(nullptr, channel1); 480 FakeTransportChannel* channel2 = CreateChannel("video", 1); 481 ASSERT_NE(nullptr, channel2); 482 FakeTransportChannel* channel3 = CreateChannel("video", 2); 483 ASSERT_NE(nullptr, channel3); 484 485 // Similar to above test, but we're now reaching the completed state, which 486 // means only one connection per FakeTransportChannel. 487 channel1->SetCandidatesGatheringComplete(); 488 channel1->SetConnectionCount(1); 489 channel1->SetWritable(true); 490 channel3->SetCandidatesGatheringComplete(); 491 channel3->SetConnectionCount(1); 492 channel3->SetConnectionCount(0); 493 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); 494 // Signal count of 1 means that the only signal emitted was "failed". 495 EXPECT_EQ(1, connection_state_signal_count_); 496 497 // Destroy the failed channel to return to "connecting" state. 498 DestroyChannel("video", 2); 499 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, 500 kTimeout); 501 EXPECT_EQ(2, connection_state_signal_count_); 502 503 // Make the remaining channel reach a connected state. 504 channel2->SetCandidatesGatheringComplete(); 505 channel2->SetConnectionCount(2); 506 channel2->SetWritable(true); 507 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); 508 EXPECT_EQ(3, connection_state_signal_count_); 509 510 // Finally, transition to completed state. 511 channel2->SetConnectionCount(1); 512 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); 513 EXPECT_EQ(4, connection_state_signal_count_); 514 } 515 516 // Make sure that if we're "connected" and remove a transport, we stay in the 517 // "connected" state. 518 TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) { 519 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 520 ASSERT_NE(nullptr, channel1); 521 FakeTransportChannel* channel2 = CreateChannel("video", 1); 522 ASSERT_NE(nullptr, channel2); 523 524 channel1->SetCandidatesGatheringComplete(); 525 channel1->SetConnectionCount(2); 526 channel1->SetWritable(true); 527 channel2->SetCandidatesGatheringComplete(); 528 channel2->SetConnectionCount(2); 529 channel2->SetWritable(true); 530 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); 531 EXPECT_EQ(1, connection_state_signal_count_); 532 533 // Destroy one channel, then "complete" the other one, so we reach 534 // a known state. 535 DestroyChannel("video", 1); 536 channel1->SetConnectionCount(1); 537 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); 538 // Signal count of 2 means the deletion didn't cause any unexpected signals 539 EXPECT_EQ(2, connection_state_signal_count_); 540 } 541 542 // If we destroy the last/only transport, we should simply transition to 543 // "connecting". 544 TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) { 545 FakeTransportChannel* channel = CreateChannel("audio", 1); 546 ASSERT_NE(nullptr, channel); 547 548 channel->SetCandidatesGatheringComplete(); 549 channel->SetConnectionCount(2); 550 channel->SetWritable(true); 551 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); 552 EXPECT_EQ(1, connection_state_signal_count_); 553 554 DestroyChannel("audio", 1); 555 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, 556 kTimeout); 557 // Signal count of 2 means the deletion didn't cause any unexpected signals 558 EXPECT_EQ(2, connection_state_signal_count_); 559 } 560 561 TEST_F(TransportControllerTest, TestSignalReceiving) { 562 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 563 ASSERT_NE(nullptr, channel1); 564 FakeTransportChannel* channel2 = CreateChannel("video", 1); 565 ASSERT_NE(nullptr, channel2); 566 567 // Should signal receiving as soon as any channel is receiving. 568 channel1->SetReceiving(true); 569 EXPECT_TRUE_WAIT(receiving_, kTimeout); 570 EXPECT_EQ(1, receiving_signal_count_); 571 572 channel2->SetReceiving(true); 573 channel1->SetReceiving(false); 574 channel2->SetReceiving(false); 575 EXPECT_TRUE_WAIT(!receiving_, kTimeout); 576 EXPECT_EQ(2, receiving_signal_count_); 577 } 578 579 TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) { 580 FakeTransportChannel* channel = CreateChannel("audio", 1); 581 ASSERT_NE(nullptr, channel); 582 channel->Connect(); 583 channel->MaybeStartGathering(); 584 // Should be in the gathering state as soon as any transport starts gathering. 585 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); 586 EXPECT_EQ(1, gathering_state_signal_count_); 587 } 588 589 TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) { 590 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 591 ASSERT_NE(nullptr, channel1); 592 FakeTransportChannel* channel2 = CreateChannel("video", 1); 593 ASSERT_NE(nullptr, channel2); 594 FakeTransportChannel* channel3 = CreateChannel("data", 1); 595 ASSERT_NE(nullptr, channel3); 596 597 channel3->Connect(); 598 channel3->MaybeStartGathering(); 599 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); 600 EXPECT_EQ(1, gathering_state_signal_count_); 601 602 // Have one channel finish gathering, then destroy it, to make sure gathering 603 // completion wasn't signalled if only one transport finished gathering. 604 channel3->SetCandidatesGatheringComplete(); 605 DestroyChannel("data", 1); 606 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout); 607 EXPECT_EQ(2, gathering_state_signal_count_); 608 609 // Make remaining channels start and then finish gathering. 610 channel1->Connect(); 611 channel1->MaybeStartGathering(); 612 channel2->Connect(); 613 channel2->MaybeStartGathering(); 614 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); 615 EXPECT_EQ(3, gathering_state_signal_count_); 616 617 channel1->SetCandidatesGatheringComplete(); 618 channel2->SetCandidatesGatheringComplete(); 619 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); 620 EXPECT_EQ(4, gathering_state_signal_count_); 621 } 622 623 // Test that when the last transport that hasn't finished connecting and/or 624 // gathering is destroyed, the aggregate state jumps to "completed". This can 625 // happen if, for example, we have an audio and video transport, the audio 626 // transport completes, then we start bundling video on the audio transport. 627 TEST_F(TransportControllerTest, 628 TestSignalingWhenLastIncompleteTransportDestroyed) { 629 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); 630 FakeTransportChannel* channel1 = CreateChannel("audio", 1); 631 ASSERT_NE(nullptr, channel1); 632 FakeTransportChannel* channel2 = CreateChannel("video", 1); 633 ASSERT_NE(nullptr, channel2); 634 635 channel1->SetCandidatesGatheringComplete(); 636 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); 637 EXPECT_EQ(1, gathering_state_signal_count_); 638 639 channel1->SetConnectionCount(1); 640 channel1->SetWritable(true); 641 DestroyChannel("video", 1); 642 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); 643 EXPECT_EQ(1, connection_state_signal_count_); 644 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); 645 EXPECT_EQ(2, gathering_state_signal_count_); 646 } 647 648 TEST_F(TransportControllerTest, TestSignalCandidatesGathered) { 649 FakeTransportChannel* channel = CreateChannel("audio", 1); 650 ASSERT_NE(nullptr, channel); 651 652 // Transport won't signal candidates until it has a local description. 653 TransportDescription local_desc( 654 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, 655 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); 656 std::string err; 657 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( 658 "audio", local_desc, cricket::CA_OFFER, &err)); 659 transport_controller_->MaybeStartGathering(); 660 661 channel->SignalCandidateGathered(channel, CreateCandidate(1)); 662 EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout); 663 EXPECT_EQ(1U, candidates_["audio"].size()); 664 } 665 666 TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) { 667 CreateTransportControllerWithWorkerThread(); 668 CreateChannelsAndCompleteConnectionOnWorkerThread(); 669 670 // connecting --> connected --> completed 671 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); 672 EXPECT_EQ(2, connection_state_signal_count_); 673 674 EXPECT_TRUE_WAIT(receiving_, kTimeout); 675 EXPECT_EQ(1, receiving_signal_count_); 676 677 // new --> gathering --> complete 678 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); 679 EXPECT_EQ(2, gathering_state_signal_count_); 680 681 EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout); 682 EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout); 683 EXPECT_EQ(2, candidates_signal_count_); 684 685 EXPECT_TRUE(!signaled_on_non_signaling_thread_); 686 } 687