blob: f068bb52db07150d4da7129a2e37adb460ccc523 [file] [log] [blame]
deadbeefcbecd352015-09-23 11:50:27 -07001/*
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>
jbauch555604a2016-04-26 03:13:22 -070012#include <memory>
deadbeefcbecd352015-09-23 11:50:27 -070013
14#include "webrtc/base/fakesslidentity.h"
15#include "webrtc/base/gunit.h"
16#include "webrtc/base/helpers.h"
deadbeefcbecd352015-09-23 11:50:27 -070017#include "webrtc/base/sslidentity.h"
18#include "webrtc/base/thread.h"
19#include "webrtc/p2p/base/dtlstransportchannel.h"
Taylor Brandstettera1c30352016-05-13 08:15:11 -070020#include "webrtc/p2p/base/fakeportallocator.h"
deadbeefcbecd352015-09-23 11:50:27 -070021#include "webrtc/p2p/base/faketransportcontroller.h"
22#include "webrtc/p2p/base/p2ptransportchannel.h"
23#include "webrtc/p2p/base/portallocator.h"
24#include "webrtc/p2p/base/transportcontroller.h"
deadbeefcbecd352015-09-23 11:50:27 -070025
26static const int kTimeout = 100;
27static const char kIceUfrag1[] = "TESTICEUFRAG0001";
28static const char kIcePwd1[] = "TESTICEPWD00000000000001";
29static const char kIceUfrag2[] = "TESTICEUFRAG0002";
30static const char kIcePwd2[] = "TESTICEPWD00000000000002";
31
32using cricket::Candidate;
33using cricket::Candidates;
34using cricket::FakeTransportChannel;
35using cricket::FakeTransportController;
36using cricket::IceConnectionState;
37using cricket::IceGatheringState;
38using cricket::TransportChannel;
39using cricket::TransportController;
40using cricket::TransportDescription;
41using 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.
49typedef FakeTransportController TransportControllerForTest;
50
51class 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 =
Danil Chapovalov7f216b72016-05-12 09:20:31 +020084 transport_controller_->CreateTransportChannel_n(content, component);
deadbeefcbecd352015-09-23 11:50:27 -070085 return static_cast<FakeTransportChannel*>(channel);
86 }
87
88 void DestroyChannel(const std::string& content, int component) {
Danil Chapovalov7f216b72016-05-12 09:20:31 +020089 transport_controller_->DestroyTransportChannel_n(content, component);
deadbeefcbecd352015-09-23 11:50:27 -070090 }
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() {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700103 worker_thread_->Invoke<void>(
104 RTC_FROM_HERE,
105 rtc::Bind(
106 &TransportControllerTest::CreateChannelsAndCompleteConnection_w,
107 this));
deadbeefcbecd352015-09-23 11:50:27 -0700108 }
109
110 void CreateChannelsAndCompleteConnection_w() {
111 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
112 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
113 ASSERT_NE(nullptr, channel1);
114 FakeTransportChannel* channel2 = CreateChannel("video", 1);
115 ASSERT_NE(nullptr, channel2);
116
deadbeef46eed762016-01-28 13:24:37 -0800117 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
118 kIcePwd1, cricket::ICEMODE_FULL,
119 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700120 std::string err;
121 transport_controller_->SetLocalTransportDescription(
122 "audio", local_desc, cricket::CA_OFFER, &err);
123 transport_controller_->SetLocalTransportDescription(
124 "video", local_desc, cricket::CA_OFFER, &err);
125 transport_controller_->MaybeStartGathering();
126 channel1->SignalCandidateGathered(channel1, CreateCandidate(1));
127 channel2->SignalCandidateGathered(channel2, CreateCandidate(1));
128 channel1->SetCandidatesGatheringComplete();
129 channel2->SetCandidatesGatheringComplete();
130 channel1->SetConnectionCount(2);
131 channel2->SetConnectionCount(2);
132 channel1->SetReceiving(true);
133 channel2->SetReceiving(true);
134 channel1->SetWritable(true);
135 channel2->SetWritable(true);
136 channel1->SetConnectionCount(1);
137 channel2->SetConnectionCount(1);
138 }
139
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700140 cricket::IceConfig CreateIceConfig(
141 int receiving_timeout,
142 cricket::ContinualGatheringPolicy continual_gathering_policy) {
honghaiz1f429e32015-09-28 07:57:34 -0700143 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800144 config.receiving_timeout = receiving_timeout;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700145 config.continual_gathering_policy = continual_gathering_policy;
honghaiz1f429e32015-09-28 07:57:34 -0700146 return config;
147 }
148
deadbeefcbecd352015-09-23 11:50:27 -0700149 protected:
150 void OnConnectionState(IceConnectionState state) {
151 if (!signaling_thread_->IsCurrent()) {
152 signaled_on_non_signaling_thread_ = true;
153 }
154 connection_state_ = state;
155 ++connection_state_signal_count_;
156 }
157
158 void OnReceiving(bool receiving) {
159 if (!signaling_thread_->IsCurrent()) {
160 signaled_on_non_signaling_thread_ = true;
161 }
162 receiving_ = receiving;
163 ++receiving_signal_count_;
164 }
165
166 void OnGatheringState(IceGatheringState state) {
167 if (!signaling_thread_->IsCurrent()) {
168 signaled_on_non_signaling_thread_ = true;
169 }
170 gathering_state_ = state;
171 ++gathering_state_signal_count_;
172 }
173
174 void OnCandidatesGathered(const std::string& transport_name,
175 const Candidates& candidates) {
176 if (!signaling_thread_->IsCurrent()) {
177 signaled_on_non_signaling_thread_ = true;
178 }
179 candidates_[transport_name].insert(candidates_[transport_name].end(),
180 candidates.begin(), candidates.end());
181 ++candidates_signal_count_;
182 }
183
jbauch555604a2016-04-26 03:13:22 -0700184 std::unique_ptr<rtc::Thread> worker_thread_; // Not used for most tests.
185 std::unique_ptr<TransportControllerForTest> transport_controller_;
deadbeefcbecd352015-09-23 11:50:27 -0700186
187 // Information received from signals from transport controller.
188 IceConnectionState connection_state_ = cricket::kIceConnectionConnecting;
189 bool receiving_ = false;
190 IceGatheringState gathering_state_ = cricket::kIceGatheringNew;
191 // transport_name => candidates
192 std::map<std::string, Candidates> candidates_;
193 // Counts of each signal emitted.
194 int connection_state_signal_count_ = 0;
195 int receiving_signal_count_ = 0;
196 int gathering_state_signal_count_ = 0;
197 int candidates_signal_count_ = 0;
198
199 // Used to make sure signals only come on signaling thread.
200 rtc::Thread* const signaling_thread_ = nullptr;
201 bool signaled_on_non_signaling_thread_ = false;
202};
203
honghaiz1f429e32015-09-28 07:57:34 -0700204TEST_F(TransportControllerTest, TestSetIceConfig) {
deadbeefcbecd352015-09-23 11:50:27 -0700205 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
206 ASSERT_NE(nullptr, channel1);
207
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700208 transport_controller_->SetIceConfig(
209 CreateIceConfig(1000, cricket::GATHER_CONTINUALLY));
deadbeefcbecd352015-09-23 11:50:27 -0700210 EXPECT_EQ(1000, channel1->receiving_timeout());
honghaiz1f429e32015-09-28 07:57:34 -0700211 EXPECT_TRUE(channel1->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700212
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700213 transport_controller_->SetIceConfig(
214 CreateIceConfig(1000, cricket::GATHER_CONTINUALLY_AND_RECOVER));
deadbeefcbecd352015-09-23 11:50:27 -0700215 // Test that value stored in controller is applied to new channels.
216 FakeTransportChannel* channel2 = CreateChannel("video", 1);
217 ASSERT_NE(nullptr, channel2);
218 EXPECT_EQ(1000, channel2->receiving_timeout());
honghaiz1f429e32015-09-28 07:57:34 -0700219 EXPECT_TRUE(channel2->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700220}
221
222TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) {
223 EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion(
224 rtc::SSL_PROTOCOL_DTLS_12));
225 FakeTransportChannel* channel = CreateChannel("audio", 1);
226
227 ASSERT_NE(nullptr, channel);
228 EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, channel->ssl_max_protocol_version());
229
230 // Setting max version after transport is created should fail.
231 EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion(
232 rtc::SSL_PROTOCOL_DTLS_10));
233}
234
235TEST_F(TransportControllerTest, TestSetIceRole) {
236 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
237 ASSERT_NE(nullptr, channel1);
238
239 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
240 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
241 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
242 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole());
243
244 // Test that value stored in controller is applied to new channels.
245 FakeTransportChannel* channel2 = CreateChannel("video", 1);
246 ASSERT_NE(nullptr, channel2);
247 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
248}
249
250// Test that when one channel encounters a role conflict, the ICE role is
251// swapped on every channel.
252TEST_F(TransportControllerTest, TestIceRoleConflict) {
253 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
254 ASSERT_NE(nullptr, channel1);
255 FakeTransportChannel* channel2 = CreateChannel("video", 1);
256 ASSERT_NE(nullptr, channel2);
257
258 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
259 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
260 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
261
262 channel1->SignalRoleConflict(channel1);
263 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole());
264 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
deadbeef1c206102016-05-27 13:34:37 -0700265
266 // Should be able to handle a second role conflict. The remote endpoint can
267 // change its role/tie-breaker when it does an ICE restart.
268 channel2->SignalRoleConflict(channel2);
269 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
270 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
deadbeefcbecd352015-09-23 11:50:27 -0700271}
272
273TEST_F(TransportControllerTest, TestGetSslRole) {
274 FakeTransportChannel* channel = CreateChannel("audio", 1);
275 ASSERT_NE(nullptr, channel);
276 ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT));
277 rtc::SSLRole role;
Taylor Brandstetterf475d362016-01-08 15:35:57 -0800278 EXPECT_FALSE(transport_controller_->GetSslRole("video", &role));
279 EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role));
deadbeefcbecd352015-09-23 11:50:27 -0700280 EXPECT_EQ(rtc::SSL_CLIENT, role);
281}
282
283TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
284 rtc::scoped_refptr<rtc::RTCCertificate> certificate1 =
jbauch555604a2016-04-26 03:13:22 -0700285 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800286 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700287 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 =
jbauch555604a2016-04-26 03:13:22 -0700288 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800289 rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700290 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;
291
292 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
293 ASSERT_NE(nullptr, channel1);
294
295 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
296 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
297 "audio", &returned_certificate));
298 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
299 returned_certificate->identity()->certificate().ToPEMString());
300
301 // Should fail if called for a nonexistant transport.
302 EXPECT_FALSE(transport_controller_->GetLocalCertificate(
303 "video", &returned_certificate));
304
305 // Test that identity stored in controller is applied to new channels.
306 FakeTransportChannel* channel2 = CreateChannel("video", 1);
307 ASSERT_NE(nullptr, channel2);
308 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
309 "video", &returned_certificate));
310 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
311 returned_certificate->identity()->certificate().ToPEMString());
312
313 // Shouldn't be able to change the identity once set.
314 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
315}
316
317TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
318 rtc::FakeSSLCertificate fake_certificate("fake_data");
deadbeefcbecd352015-09-23 11:50:27 -0700319
320 FakeTransportChannel* channel = CreateChannel("audio", 1);
321 ASSERT_NE(nullptr, channel);
322
323 channel->SetRemoteSSLCertificate(&fake_certificate);
jbauch555604a2016-04-26 03:13:22 -0700324 std::unique_ptr<rtc::SSLCertificate> returned_certificate =
kwibergb4d01c42016-04-06 05:15:06 -0700325 transport_controller_->GetRemoteSSLCertificate("audio");
326 EXPECT_TRUE(returned_certificate);
deadbeefcbecd352015-09-23 11:50:27 -0700327 EXPECT_EQ(fake_certificate.ToPEMString(),
328 returned_certificate->ToPEMString());
329
330 // Should fail if called for a nonexistant transport.
kwibergb4d01c42016-04-06 05:15:06 -0700331 EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate("video"));
deadbeefcbecd352015-09-23 11:50:27 -0700332}
333
334TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
335 FakeTransportChannel* channel = CreateChannel("audio", 1);
336 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800337 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
338 kIcePwd1, cricket::ICEMODE_FULL,
339 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700340 std::string err;
341 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
342 "audio", local_desc, cricket::CA_OFFER, &err));
343 // Check that ICE ufrag and pwd were propagated to channel.
344 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag());
345 EXPECT_EQ(kIcePwd1, channel->ice_pwd());
346 // After setting local description, we should be able to start gathering
347 // candidates.
348 transport_controller_->MaybeStartGathering();
349 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
350 EXPECT_EQ(1, gathering_state_signal_count_);
351}
352
353TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
354 FakeTransportChannel* channel = CreateChannel("audio", 1);
355 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800356 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
357 kIcePwd1, cricket::ICEMODE_FULL,
358 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700359 std::string err;
360 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
361 "audio", remote_desc, cricket::CA_OFFER, &err));
362 // Check that ICE ufrag and pwd were propagated to channel.
363 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag());
364 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd());
365}
366
367TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
368 FakeTransportChannel* channel = CreateChannel("audio", 1);
369 ASSERT_NE(nullptr, channel);
370 Candidates candidates;
371 candidates.push_back(CreateCandidate(1));
372 std::string err;
373 EXPECT_TRUE(
374 transport_controller_->AddRemoteCandidates("audio", candidates, &err));
375 EXPECT_EQ(1U, channel->remote_candidates().size());
376}
377
378TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
379 FakeTransportChannel* channel = CreateChannel("audio", 1);
380 ASSERT_NE(nullptr, channel);
381 // We expect to be ready for remote candidates only after local and remote
382 // descriptions are set.
383 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
384
385 std::string err;
deadbeef46eed762016-01-28 13:24:37 -0800386 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
387 kIcePwd1, cricket::ICEMODE_FULL,
388 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700389 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
390 "audio", remote_desc, cricket::CA_OFFER, &err));
391 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
392
deadbeef46eed762016-01-28 13:24:37 -0800393 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
394 kIcePwd2, cricket::ICEMODE_FULL,
395 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700396 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
397 "audio", local_desc, cricket::CA_ANSWER, &err));
398 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio"));
399}
400
401TEST_F(TransportControllerTest, TestGetStats) {
402 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
403 ASSERT_NE(nullptr, channel1);
404 FakeTransportChannel* channel2 = CreateChannel("audio", 2);
405 ASSERT_NE(nullptr, channel2);
406 FakeTransportChannel* channel3 = CreateChannel("video", 1);
407 ASSERT_NE(nullptr, channel3);
408
409 TransportStats stats;
410 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
411 EXPECT_EQ("audio", stats.transport_name);
412 EXPECT_EQ(2U, stats.channel_stats.size());
413}
414
415// Test that transport gets destroyed when it has no more channels.
416TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
417 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
418 ASSERT_NE(nullptr, channel1);
419 FakeTransportChannel* channel2 = CreateChannel("audio", 1);
420 ASSERT_NE(nullptr, channel2);
421 ASSERT_EQ(channel1, channel2);
422 FakeTransportChannel* channel3 = CreateChannel("audio", 2);
423 ASSERT_NE(nullptr, channel3);
424
425 // Using GetStats to check if transport is destroyed from an outside class's
426 // perspective.
427 TransportStats stats;
428 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
429 DestroyChannel("audio", 2);
430 DestroyChannel("audio", 1);
431 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
432 DestroyChannel("audio", 1);
433 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats));
434}
435
436TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
437 // Need controlling ICE role to get in failed state.
438 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
439 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
440 ASSERT_NE(nullptr, channel1);
441 FakeTransportChannel* channel2 = CreateChannel("video", 1);
442 ASSERT_NE(nullptr, channel2);
443
444 // Should signal "failed" if any channel failed; channel is considered failed
445 // if it previously had a connection but now has none, and gathering is
446 // complete.
447 channel1->SetCandidatesGatheringComplete();
448 channel1->SetConnectionCount(1);
449 channel1->SetConnectionCount(0);
450 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
451 EXPECT_EQ(1, connection_state_signal_count_);
452}
453
454TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
455 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
456 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
457 ASSERT_NE(nullptr, channel1);
458 FakeTransportChannel* channel2 = CreateChannel("video", 1);
459 ASSERT_NE(nullptr, channel2);
460 FakeTransportChannel* channel3 = CreateChannel("video", 2);
461 ASSERT_NE(nullptr, channel3);
462
463 // First, have one channel connect, and another fail, to ensure that
464 // the first channel connecting didn't trigger a "connected" state signal.
465 // We should only get a signal when all are connected.
466 channel1->SetConnectionCount(2);
467 channel1->SetWritable(true);
468 channel3->SetCandidatesGatheringComplete();
469 channel3->SetConnectionCount(1);
470 channel3->SetConnectionCount(0);
471 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
472 // Signal count of 1 means that the only signal emitted was "failed".
473 EXPECT_EQ(1, connection_state_signal_count_);
474
475 // Destroy the failed channel to return to "connecting" state.
476 DestroyChannel("video", 2);
477 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
478 kTimeout);
479 EXPECT_EQ(2, connection_state_signal_count_);
480
481 // Make the remaining channel reach a connected state.
482 channel2->SetConnectionCount(2);
483 channel2->SetWritable(true);
484 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
485 EXPECT_EQ(3, connection_state_signal_count_);
486}
487
488TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
489 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
490 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
491 ASSERT_NE(nullptr, channel1);
492 FakeTransportChannel* channel2 = CreateChannel("video", 1);
493 ASSERT_NE(nullptr, channel2);
494 FakeTransportChannel* channel3 = CreateChannel("video", 2);
495 ASSERT_NE(nullptr, channel3);
496
497 // Similar to above test, but we're now reaching the completed state, which
498 // means only one connection per FakeTransportChannel.
499 channel1->SetCandidatesGatheringComplete();
500 channel1->SetConnectionCount(1);
501 channel1->SetWritable(true);
502 channel3->SetCandidatesGatheringComplete();
503 channel3->SetConnectionCount(1);
504 channel3->SetConnectionCount(0);
505 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
506 // Signal count of 1 means that the only signal emitted was "failed".
507 EXPECT_EQ(1, connection_state_signal_count_);
508
509 // Destroy the failed channel to return to "connecting" state.
510 DestroyChannel("video", 2);
511 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
512 kTimeout);
513 EXPECT_EQ(2, connection_state_signal_count_);
514
515 // Make the remaining channel reach a connected state.
516 channel2->SetCandidatesGatheringComplete();
517 channel2->SetConnectionCount(2);
518 channel2->SetWritable(true);
519 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
520 EXPECT_EQ(3, connection_state_signal_count_);
521
522 // Finally, transition to completed state.
523 channel2->SetConnectionCount(1);
524 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
525 EXPECT_EQ(4, connection_state_signal_count_);
526}
527
528// Make sure that if we're "connected" and remove a transport, we stay in the
529// "connected" state.
530TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
531 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
532 ASSERT_NE(nullptr, channel1);
533 FakeTransportChannel* channel2 = CreateChannel("video", 1);
534 ASSERT_NE(nullptr, channel2);
535
536 channel1->SetCandidatesGatheringComplete();
537 channel1->SetConnectionCount(2);
538 channel1->SetWritable(true);
539 channel2->SetCandidatesGatheringComplete();
540 channel2->SetConnectionCount(2);
541 channel2->SetWritable(true);
542 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
543 EXPECT_EQ(1, connection_state_signal_count_);
544
545 // Destroy one channel, then "complete" the other one, so we reach
546 // a known state.
547 DestroyChannel("video", 1);
548 channel1->SetConnectionCount(1);
549 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
550 // Signal count of 2 means the deletion didn't cause any unexpected signals
551 EXPECT_EQ(2, connection_state_signal_count_);
552}
553
554// If we destroy the last/only transport, we should simply transition to
555// "connecting".
556TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
557 FakeTransportChannel* channel = CreateChannel("audio", 1);
558 ASSERT_NE(nullptr, channel);
559
560 channel->SetCandidatesGatheringComplete();
561 channel->SetConnectionCount(2);
562 channel->SetWritable(true);
563 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
564 EXPECT_EQ(1, connection_state_signal_count_);
565
566 DestroyChannel("audio", 1);
567 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
568 kTimeout);
569 // Signal count of 2 means the deletion didn't cause any unexpected signals
570 EXPECT_EQ(2, connection_state_signal_count_);
571}
572
573TEST_F(TransportControllerTest, TestSignalReceiving) {
574 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
575 ASSERT_NE(nullptr, channel1);
576 FakeTransportChannel* channel2 = CreateChannel("video", 1);
577 ASSERT_NE(nullptr, channel2);
578
579 // Should signal receiving as soon as any channel is receiving.
580 channel1->SetReceiving(true);
581 EXPECT_TRUE_WAIT(receiving_, kTimeout);
582 EXPECT_EQ(1, receiving_signal_count_);
583
584 channel2->SetReceiving(true);
585 channel1->SetReceiving(false);
586 channel2->SetReceiving(false);
587 EXPECT_TRUE_WAIT(!receiving_, kTimeout);
588 EXPECT_EQ(2, receiving_signal_count_);
589}
590
591TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
592 FakeTransportChannel* channel = CreateChannel("audio", 1);
593 ASSERT_NE(nullptr, channel);
deadbeefcbecd352015-09-23 11:50:27 -0700594 channel->MaybeStartGathering();
595 // Should be in the gathering state as soon as any transport starts gathering.
596 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
597 EXPECT_EQ(1, gathering_state_signal_count_);
598}
599
600TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
601 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
602 ASSERT_NE(nullptr, channel1);
603 FakeTransportChannel* channel2 = CreateChannel("video", 1);
604 ASSERT_NE(nullptr, channel2);
605 FakeTransportChannel* channel3 = CreateChannel("data", 1);
606 ASSERT_NE(nullptr, channel3);
607
deadbeefcbecd352015-09-23 11:50:27 -0700608 channel3->MaybeStartGathering();
609 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
610 EXPECT_EQ(1, gathering_state_signal_count_);
611
612 // Have one channel finish gathering, then destroy it, to make sure gathering
613 // completion wasn't signalled if only one transport finished gathering.
614 channel3->SetCandidatesGatheringComplete();
615 DestroyChannel("data", 1);
616 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout);
617 EXPECT_EQ(2, gathering_state_signal_count_);
618
619 // Make remaining channels start and then finish gathering.
deadbeefcbecd352015-09-23 11:50:27 -0700620 channel1->MaybeStartGathering();
deadbeefcbecd352015-09-23 11:50:27 -0700621 channel2->MaybeStartGathering();
622 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
623 EXPECT_EQ(3, gathering_state_signal_count_);
624
625 channel1->SetCandidatesGatheringComplete();
626 channel2->SetCandidatesGatheringComplete();
627 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
628 EXPECT_EQ(4, gathering_state_signal_count_);
629}
630
631// Test that when the last transport that hasn't finished connecting and/or
632// gathering is destroyed, the aggregate state jumps to "completed". This can
633// happen if, for example, we have an audio and video transport, the audio
634// transport completes, then we start bundling video on the audio transport.
635TEST_F(TransportControllerTest,
636 TestSignalingWhenLastIncompleteTransportDestroyed) {
637 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
638 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
639 ASSERT_NE(nullptr, channel1);
640 FakeTransportChannel* channel2 = CreateChannel("video", 1);
641 ASSERT_NE(nullptr, channel2);
642
643 channel1->SetCandidatesGatheringComplete();
644 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
645 EXPECT_EQ(1, gathering_state_signal_count_);
646
647 channel1->SetConnectionCount(1);
648 channel1->SetWritable(true);
649 DestroyChannel("video", 1);
650 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
651 EXPECT_EQ(1, connection_state_signal_count_);
652 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
653 EXPECT_EQ(2, gathering_state_signal_count_);
654}
655
656TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
657 FakeTransportChannel* channel = CreateChannel("audio", 1);
658 ASSERT_NE(nullptr, channel);
659
660 // Transport won't signal candidates until it has a local description.
deadbeef46eed762016-01-28 13:24:37 -0800661 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
662 kIcePwd1, cricket::ICEMODE_FULL,
663 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700664 std::string err;
665 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
666 "audio", local_desc, cricket::CA_OFFER, &err));
667 transport_controller_->MaybeStartGathering();
668
669 channel->SignalCandidateGathered(channel, CreateCandidate(1));
670 EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout);
671 EXPECT_EQ(1U, candidates_["audio"].size());
672}
673
674TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) {
675 CreateTransportControllerWithWorkerThread();
676 CreateChannelsAndCompleteConnectionOnWorkerThread();
677
678 // connecting --> connected --> completed
679 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
680 EXPECT_EQ(2, connection_state_signal_count_);
681
682 EXPECT_TRUE_WAIT(receiving_, kTimeout);
683 EXPECT_EQ(1, receiving_signal_count_);
684
685 // new --> gathering --> complete
686 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
687 EXPECT_EQ(2, gathering_state_signal_count_);
688
689 EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout);
690 EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout);
691 EXPECT_EQ(2, candidates_signal_count_);
692
693 EXPECT_TRUE(!signaled_on_non_signaling_thread_);
694}