• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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