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:
TransportControllerTest()54 TransportControllerTest()
55 : transport_controller_(new TransportControllerForTest()),
56 signaling_thread_(rtc::Thread::Current()) {
57 ConnectTransportControllerSignals();
58 }
59
CreateTransportControllerWithWorkerThread()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
ConnectTransportControllerSignals()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
CreateChannel(const std::string & content,int component)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
DestroyChannel(const std::string & content,int component)88 void DestroyChannel(const std::string& content, int component) {
89 transport_controller_->DestroyTransportChannel_w(content, component);
90 }
91
CreateCandidate(int component)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.
CreateChannelsAndCompleteConnectionOnWorkerThread()102 void CreateChannelsAndCompleteConnectionOnWorkerThread() {
103 worker_thread_->Invoke<void>(rtc::Bind(
104 &TransportControllerTest::CreateChannelsAndCompleteConnection_w, this));
105 }
106
CreateChannelsAndCompleteConnection_w()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
CreateIceConfig(int receiving_timeout_ms,bool gather_continually)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:
OnConnectionState(IceConnectionState state)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
OnReceiving(bool receiving)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
OnGatheringState(IceGatheringState state)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
OnCandidatesGathered(const std::string & transport_name,const Candidates & candidates)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
TEST_F(TransportControllerTest,TestSetIceConfig)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
TEST_F(TransportControllerTest,TestSetSslMaxProtocolVersion)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
TEST_F(TransportControllerTest,TestSetIceRole)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.
TEST_F(TransportControllerTest,TestIceRoleConflict)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
TEST_F(TransportControllerTest,TestGetSslRole)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
TEST_F(TransportControllerTest,TestSetAndGetLocalCertificate)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
TEST_F(TransportControllerTest,TestGetRemoteSSLCertificate)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
TEST_F(TransportControllerTest,TestSetLocalTransportDescription)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
TEST_F(TransportControllerTest,TestSetRemoteTransportDescription)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
TEST_F(TransportControllerTest,TestAddRemoteCandidates)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
TEST_F(TransportControllerTest,TestReadyForRemoteCandidates)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
TEST_F(TransportControllerTest,TestGetStats)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.
TEST_F(TransportControllerTest,TestCreateAndDestroyChannel)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
TEST_F(TransportControllerTest,TestSignalConnectionStateFailed)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
TEST_F(TransportControllerTest,TestSignalConnectionStateConnected)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
TEST_F(TransportControllerTest,TestSignalConnectionStateComplete)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.
TEST_F(TransportControllerTest,TestDestroyTransportAndStayConnected)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".
TEST_F(TransportControllerTest,TestDestroyLastTransportWhileConnected)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
TEST_F(TransportControllerTest,TestSignalReceiving)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
TEST_F(TransportControllerTest,TestSignalGatheringStateGathering)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
TEST_F(TransportControllerTest,TestSignalGatheringStateComplete)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.
TEST_F(TransportControllerTest,TestSignalingWhenLastIncompleteTransportDestroyed)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
TEST_F(TransportControllerTest,TestSignalCandidatesGathered)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
TEST_F(TransportControllerTest,TestSignalingOccursOnSignalingThread)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