blob: 4ca481f241f192a051a72d4f72f20b0988b6698e [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 Zhang049fbb12016-03-07 11:13:07 -0800140 cricket::IceConfig CreateIceConfig(int receiving_timeout,
honghaiz1f429e32015-09-28 07:57:34 -0700141 bool gather_continually) {
142 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800143 config.receiving_timeout = receiving_timeout;
honghaiz1f429e32015-09-28 07:57:34 -0700144 config.gather_continually = gather_continually;
145 return config;
146 }
147
deadbeefcbecd352015-09-23 11:50:27 -0700148 protected:
149 void OnConnectionState(IceConnectionState state) {
150 if (!signaling_thread_->IsCurrent()) {
151 signaled_on_non_signaling_thread_ = true;
152 }
153 connection_state_ = state;
154 ++connection_state_signal_count_;
155 }
156
157 void OnReceiving(bool receiving) {
158 if (!signaling_thread_->IsCurrent()) {
159 signaled_on_non_signaling_thread_ = true;
160 }
161 receiving_ = receiving;
162 ++receiving_signal_count_;
163 }
164
165 void OnGatheringState(IceGatheringState state) {
166 if (!signaling_thread_->IsCurrent()) {
167 signaled_on_non_signaling_thread_ = true;
168 }
169 gathering_state_ = state;
170 ++gathering_state_signal_count_;
171 }
172
173 void OnCandidatesGathered(const std::string& transport_name,
174 const Candidates& candidates) {
175 if (!signaling_thread_->IsCurrent()) {
176 signaled_on_non_signaling_thread_ = true;
177 }
178 candidates_[transport_name].insert(candidates_[transport_name].end(),
179 candidates.begin(), candidates.end());
180 ++candidates_signal_count_;
181 }
182
jbauch555604a2016-04-26 03:13:22 -0700183 std::unique_ptr<rtc::Thread> worker_thread_; // Not used for most tests.
184 std::unique_ptr<TransportControllerForTest> transport_controller_;
deadbeefcbecd352015-09-23 11:50:27 -0700185
186 // Information received from signals from transport controller.
187 IceConnectionState connection_state_ = cricket::kIceConnectionConnecting;
188 bool receiving_ = false;
189 IceGatheringState gathering_state_ = cricket::kIceGatheringNew;
190 // transport_name => candidates
191 std::map<std::string, Candidates> candidates_;
192 // Counts of each signal emitted.
193 int connection_state_signal_count_ = 0;
194 int receiving_signal_count_ = 0;
195 int gathering_state_signal_count_ = 0;
196 int candidates_signal_count_ = 0;
197
198 // Used to make sure signals only come on signaling thread.
199 rtc::Thread* const signaling_thread_ = nullptr;
200 bool signaled_on_non_signaling_thread_ = false;
201};
202
honghaiz1f429e32015-09-28 07:57:34 -0700203TEST_F(TransportControllerTest, TestSetIceConfig) {
deadbeefcbecd352015-09-23 11:50:27 -0700204 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
205 ASSERT_NE(nullptr, channel1);
206
honghaiz1f429e32015-09-28 07:57:34 -0700207 transport_controller_->SetIceConfig(CreateIceConfig(1000, true));
deadbeefcbecd352015-09-23 11:50:27 -0700208 EXPECT_EQ(1000, channel1->receiving_timeout());
honghaiz1f429e32015-09-28 07:57:34 -0700209 EXPECT_TRUE(channel1->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700210
211 // Test that value stored in controller is applied to new channels.
212 FakeTransportChannel* channel2 = CreateChannel("video", 1);
213 ASSERT_NE(nullptr, channel2);
214 EXPECT_EQ(1000, channel2->receiving_timeout());
honghaiz1f429e32015-09-28 07:57:34 -0700215 EXPECT_TRUE(channel2->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700216}
217
218TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) {
219 EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion(
220 rtc::SSL_PROTOCOL_DTLS_12));
221 FakeTransportChannel* channel = CreateChannel("audio", 1);
222
223 ASSERT_NE(nullptr, channel);
224 EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, channel->ssl_max_protocol_version());
225
226 // Setting max version after transport is created should fail.
227 EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion(
228 rtc::SSL_PROTOCOL_DTLS_10));
229}
230
231TEST_F(TransportControllerTest, TestSetIceRole) {
232 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
233 ASSERT_NE(nullptr, channel1);
234
235 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
236 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
237 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
238 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole());
239
240 // Test that value stored in controller is applied to new channels.
241 FakeTransportChannel* channel2 = CreateChannel("video", 1);
242 ASSERT_NE(nullptr, channel2);
243 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
244}
245
246// Test that when one channel encounters a role conflict, the ICE role is
247// swapped on every channel.
248TEST_F(TransportControllerTest, TestIceRoleConflict) {
249 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
250 ASSERT_NE(nullptr, channel1);
251 FakeTransportChannel* channel2 = CreateChannel("video", 1);
252 ASSERT_NE(nullptr, channel2);
253
254 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
255 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
256 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
257
258 channel1->SignalRoleConflict(channel1);
259 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole());
260 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
deadbeef1c206102016-05-27 13:34:37 -0700261
262 // Should be able to handle a second role conflict. The remote endpoint can
263 // change its role/tie-breaker when it does an ICE restart.
264 channel2->SignalRoleConflict(channel2);
265 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
266 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
deadbeefcbecd352015-09-23 11:50:27 -0700267}
268
269TEST_F(TransportControllerTest, TestGetSslRole) {
270 FakeTransportChannel* channel = CreateChannel("audio", 1);
271 ASSERT_NE(nullptr, channel);
272 ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT));
273 rtc::SSLRole role;
Taylor Brandstetterf475d362016-01-08 15:35:57 -0800274 EXPECT_FALSE(transport_controller_->GetSslRole("video", &role));
275 EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role));
deadbeefcbecd352015-09-23 11:50:27 -0700276 EXPECT_EQ(rtc::SSL_CLIENT, role);
277}
278
279TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
280 rtc::scoped_refptr<rtc::RTCCertificate> certificate1 =
jbauch555604a2016-04-26 03:13:22 -0700281 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800282 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700283 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 =
jbauch555604a2016-04-26 03:13:22 -0700284 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800285 rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700286 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;
287
288 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
289 ASSERT_NE(nullptr, channel1);
290
291 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
292 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
293 "audio", &returned_certificate));
294 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
295 returned_certificate->identity()->certificate().ToPEMString());
296
297 // Should fail if called for a nonexistant transport.
298 EXPECT_FALSE(transport_controller_->GetLocalCertificate(
299 "video", &returned_certificate));
300
301 // Test that identity stored in controller is applied to new channels.
302 FakeTransportChannel* channel2 = CreateChannel("video", 1);
303 ASSERT_NE(nullptr, channel2);
304 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
305 "video", &returned_certificate));
306 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
307 returned_certificate->identity()->certificate().ToPEMString());
308
309 // Shouldn't be able to change the identity once set.
310 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
311}
312
313TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
314 rtc::FakeSSLCertificate fake_certificate("fake_data");
deadbeefcbecd352015-09-23 11:50:27 -0700315
316 FakeTransportChannel* channel = CreateChannel("audio", 1);
317 ASSERT_NE(nullptr, channel);
318
319 channel->SetRemoteSSLCertificate(&fake_certificate);
jbauch555604a2016-04-26 03:13:22 -0700320 std::unique_ptr<rtc::SSLCertificate> returned_certificate =
kwibergb4d01c42016-04-06 05:15:06 -0700321 transport_controller_->GetRemoteSSLCertificate("audio");
322 EXPECT_TRUE(returned_certificate);
deadbeefcbecd352015-09-23 11:50:27 -0700323 EXPECT_EQ(fake_certificate.ToPEMString(),
324 returned_certificate->ToPEMString());
325
326 // Should fail if called for a nonexistant transport.
kwibergb4d01c42016-04-06 05:15:06 -0700327 EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate("video"));
deadbeefcbecd352015-09-23 11:50:27 -0700328}
329
330TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
331 FakeTransportChannel* channel = CreateChannel("audio", 1);
332 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800333 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
334 kIcePwd1, cricket::ICEMODE_FULL,
335 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700336 std::string err;
337 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
338 "audio", local_desc, cricket::CA_OFFER, &err));
339 // Check that ICE ufrag and pwd were propagated to channel.
340 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag());
341 EXPECT_EQ(kIcePwd1, channel->ice_pwd());
342 // After setting local description, we should be able to start gathering
343 // candidates.
344 transport_controller_->MaybeStartGathering();
345 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
346 EXPECT_EQ(1, gathering_state_signal_count_);
347}
348
349TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
350 FakeTransportChannel* channel = CreateChannel("audio", 1);
351 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800352 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
353 kIcePwd1, cricket::ICEMODE_FULL,
354 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700355 std::string err;
356 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
357 "audio", remote_desc, cricket::CA_OFFER, &err));
358 // Check that ICE ufrag and pwd were propagated to channel.
359 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag());
360 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd());
361}
362
363TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
364 FakeTransportChannel* channel = CreateChannel("audio", 1);
365 ASSERT_NE(nullptr, channel);
366 Candidates candidates;
367 candidates.push_back(CreateCandidate(1));
368 std::string err;
369 EXPECT_TRUE(
370 transport_controller_->AddRemoteCandidates("audio", candidates, &err));
371 EXPECT_EQ(1U, channel->remote_candidates().size());
372}
373
374TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
375 FakeTransportChannel* channel = CreateChannel("audio", 1);
376 ASSERT_NE(nullptr, channel);
377 // We expect to be ready for remote candidates only after local and remote
378 // descriptions are set.
379 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
380
381 std::string err;
deadbeef46eed762016-01-28 13:24:37 -0800382 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
383 kIcePwd1, cricket::ICEMODE_FULL,
384 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700385 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
386 "audio", remote_desc, cricket::CA_OFFER, &err));
387 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
388
deadbeef46eed762016-01-28 13:24:37 -0800389 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
390 kIcePwd2, cricket::ICEMODE_FULL,
391 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700392 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
393 "audio", local_desc, cricket::CA_ANSWER, &err));
394 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio"));
395}
396
397TEST_F(TransportControllerTest, TestGetStats) {
398 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
399 ASSERT_NE(nullptr, channel1);
400 FakeTransportChannel* channel2 = CreateChannel("audio", 2);
401 ASSERT_NE(nullptr, channel2);
402 FakeTransportChannel* channel3 = CreateChannel("video", 1);
403 ASSERT_NE(nullptr, channel3);
404
405 TransportStats stats;
406 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
407 EXPECT_EQ("audio", stats.transport_name);
408 EXPECT_EQ(2U, stats.channel_stats.size());
409}
410
411// Test that transport gets destroyed when it has no more channels.
412TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
413 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
414 ASSERT_NE(nullptr, channel1);
415 FakeTransportChannel* channel2 = CreateChannel("audio", 1);
416 ASSERT_NE(nullptr, channel2);
417 ASSERT_EQ(channel1, channel2);
418 FakeTransportChannel* channel3 = CreateChannel("audio", 2);
419 ASSERT_NE(nullptr, channel3);
420
421 // Using GetStats to check if transport is destroyed from an outside class's
422 // perspective.
423 TransportStats stats;
424 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
425 DestroyChannel("audio", 2);
426 DestroyChannel("audio", 1);
427 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
428 DestroyChannel("audio", 1);
429 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats));
430}
431
432TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
433 // Need controlling ICE role to get in failed state.
434 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
435 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
436 ASSERT_NE(nullptr, channel1);
437 FakeTransportChannel* channel2 = CreateChannel("video", 1);
438 ASSERT_NE(nullptr, channel2);
439
440 // Should signal "failed" if any channel failed; channel is considered failed
441 // if it previously had a connection but now has none, and gathering is
442 // complete.
443 channel1->SetCandidatesGatheringComplete();
444 channel1->SetConnectionCount(1);
445 channel1->SetConnectionCount(0);
446 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
447 EXPECT_EQ(1, connection_state_signal_count_);
448}
449
450TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
451 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
452 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
453 ASSERT_NE(nullptr, channel1);
454 FakeTransportChannel* channel2 = CreateChannel("video", 1);
455 ASSERT_NE(nullptr, channel2);
456 FakeTransportChannel* channel3 = CreateChannel("video", 2);
457 ASSERT_NE(nullptr, channel3);
458
459 // First, have one channel connect, and another fail, to ensure that
460 // the first channel connecting didn't trigger a "connected" state signal.
461 // We should only get a signal when all are connected.
462 channel1->SetConnectionCount(2);
463 channel1->SetWritable(true);
464 channel3->SetCandidatesGatheringComplete();
465 channel3->SetConnectionCount(1);
466 channel3->SetConnectionCount(0);
467 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
468 // Signal count of 1 means that the only signal emitted was "failed".
469 EXPECT_EQ(1, connection_state_signal_count_);
470
471 // Destroy the failed channel to return to "connecting" state.
472 DestroyChannel("video", 2);
473 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
474 kTimeout);
475 EXPECT_EQ(2, connection_state_signal_count_);
476
477 // Make the remaining channel reach a connected state.
478 channel2->SetConnectionCount(2);
479 channel2->SetWritable(true);
480 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
481 EXPECT_EQ(3, connection_state_signal_count_);
482}
483
484TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
485 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
486 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
487 ASSERT_NE(nullptr, channel1);
488 FakeTransportChannel* channel2 = CreateChannel("video", 1);
489 ASSERT_NE(nullptr, channel2);
490 FakeTransportChannel* channel3 = CreateChannel("video", 2);
491 ASSERT_NE(nullptr, channel3);
492
493 // Similar to above test, but we're now reaching the completed state, which
494 // means only one connection per FakeTransportChannel.
495 channel1->SetCandidatesGatheringComplete();
496 channel1->SetConnectionCount(1);
497 channel1->SetWritable(true);
498 channel3->SetCandidatesGatheringComplete();
499 channel3->SetConnectionCount(1);
500 channel3->SetConnectionCount(0);
501 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
502 // Signal count of 1 means that the only signal emitted was "failed".
503 EXPECT_EQ(1, connection_state_signal_count_);
504
505 // Destroy the failed channel to return to "connecting" state.
506 DestroyChannel("video", 2);
507 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
508 kTimeout);
509 EXPECT_EQ(2, connection_state_signal_count_);
510
511 // Make the remaining channel reach a connected state.
512 channel2->SetCandidatesGatheringComplete();
513 channel2->SetConnectionCount(2);
514 channel2->SetWritable(true);
515 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
516 EXPECT_EQ(3, connection_state_signal_count_);
517
518 // Finally, transition to completed state.
519 channel2->SetConnectionCount(1);
520 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
521 EXPECT_EQ(4, connection_state_signal_count_);
522}
523
524// Make sure that if we're "connected" and remove a transport, we stay in the
525// "connected" state.
526TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
527 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
528 ASSERT_NE(nullptr, channel1);
529 FakeTransportChannel* channel2 = CreateChannel("video", 1);
530 ASSERT_NE(nullptr, channel2);
531
532 channel1->SetCandidatesGatheringComplete();
533 channel1->SetConnectionCount(2);
534 channel1->SetWritable(true);
535 channel2->SetCandidatesGatheringComplete();
536 channel2->SetConnectionCount(2);
537 channel2->SetWritable(true);
538 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
539 EXPECT_EQ(1, connection_state_signal_count_);
540
541 // Destroy one channel, then "complete" the other one, so we reach
542 // a known state.
543 DestroyChannel("video", 1);
544 channel1->SetConnectionCount(1);
545 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
546 // Signal count of 2 means the deletion didn't cause any unexpected signals
547 EXPECT_EQ(2, connection_state_signal_count_);
548}
549
550// If we destroy the last/only transport, we should simply transition to
551// "connecting".
552TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
553 FakeTransportChannel* channel = CreateChannel("audio", 1);
554 ASSERT_NE(nullptr, channel);
555
556 channel->SetCandidatesGatheringComplete();
557 channel->SetConnectionCount(2);
558 channel->SetWritable(true);
559 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
560 EXPECT_EQ(1, connection_state_signal_count_);
561
562 DestroyChannel("audio", 1);
563 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
564 kTimeout);
565 // Signal count of 2 means the deletion didn't cause any unexpected signals
566 EXPECT_EQ(2, connection_state_signal_count_);
567}
568
569TEST_F(TransportControllerTest, TestSignalReceiving) {
570 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
571 ASSERT_NE(nullptr, channel1);
572 FakeTransportChannel* channel2 = CreateChannel("video", 1);
573 ASSERT_NE(nullptr, channel2);
574
575 // Should signal receiving as soon as any channel is receiving.
576 channel1->SetReceiving(true);
577 EXPECT_TRUE_WAIT(receiving_, kTimeout);
578 EXPECT_EQ(1, receiving_signal_count_);
579
580 channel2->SetReceiving(true);
581 channel1->SetReceiving(false);
582 channel2->SetReceiving(false);
583 EXPECT_TRUE_WAIT(!receiving_, kTimeout);
584 EXPECT_EQ(2, receiving_signal_count_);
585}
586
587TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
588 FakeTransportChannel* channel = CreateChannel("audio", 1);
589 ASSERT_NE(nullptr, channel);
590 channel->Connect();
591 channel->MaybeStartGathering();
592 // Should be in the gathering state as soon as any transport starts gathering.
593 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
594 EXPECT_EQ(1, gathering_state_signal_count_);
595}
596
597TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
598 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
599 ASSERT_NE(nullptr, channel1);
600 FakeTransportChannel* channel2 = CreateChannel("video", 1);
601 ASSERT_NE(nullptr, channel2);
602 FakeTransportChannel* channel3 = CreateChannel("data", 1);
603 ASSERT_NE(nullptr, channel3);
604
605 channel3->Connect();
606 channel3->MaybeStartGathering();
607 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
608 EXPECT_EQ(1, gathering_state_signal_count_);
609
610 // Have one channel finish gathering, then destroy it, to make sure gathering
611 // completion wasn't signalled if only one transport finished gathering.
612 channel3->SetCandidatesGatheringComplete();
613 DestroyChannel("data", 1);
614 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout);
615 EXPECT_EQ(2, gathering_state_signal_count_);
616
617 // Make remaining channels start and then finish gathering.
618 channel1->Connect();
619 channel1->MaybeStartGathering();
620 channel2->Connect();
621 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}