blob: fdb99a733c6c8626f1ca803d240f49182338bdfd [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() {
103 worker_thread_->Invoke<void>(rtc::Bind(
104 &TransportControllerTest::CreateChannelsAndCompleteConnection_w, this));
105 }
106
107 void CreateChannelsAndCompleteConnection_w() {
108 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
109 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
110 ASSERT_NE(nullptr, channel1);
111 FakeTransportChannel* channel2 = CreateChannel("video", 1);
112 ASSERT_NE(nullptr, channel2);
113
deadbeef46eed762016-01-28 13:24:37 -0800114 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
115 kIcePwd1, cricket::ICEMODE_FULL,
116 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700117 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
Honghai Zhang049fbb12016-03-07 11:13:07 -0800137 cricket::IceConfig CreateIceConfig(int receiving_timeout,
honghaiz1f429e32015-09-28 07:57:34 -0700138 bool gather_continually) {
139 cricket::IceConfig config;
Honghai Zhang049fbb12016-03-07 11:13:07 -0800140 config.receiving_timeout = receiving_timeout;
honghaiz1f429e32015-09-28 07:57:34 -0700141 config.gather_continually = gather_continually;
142 return config;
143 }
144
deadbeefcbecd352015-09-23 11:50:27 -0700145 protected:
146 void OnConnectionState(IceConnectionState state) {
147 if (!signaling_thread_->IsCurrent()) {
148 signaled_on_non_signaling_thread_ = true;
149 }
150 connection_state_ = state;
151 ++connection_state_signal_count_;
152 }
153
154 void OnReceiving(bool receiving) {
155 if (!signaling_thread_->IsCurrent()) {
156 signaled_on_non_signaling_thread_ = true;
157 }
158 receiving_ = receiving;
159 ++receiving_signal_count_;
160 }
161
162 void OnGatheringState(IceGatheringState state) {
163 if (!signaling_thread_->IsCurrent()) {
164 signaled_on_non_signaling_thread_ = true;
165 }
166 gathering_state_ = state;
167 ++gathering_state_signal_count_;
168 }
169
170 void OnCandidatesGathered(const std::string& transport_name,
171 const Candidates& candidates) {
172 if (!signaling_thread_->IsCurrent()) {
173 signaled_on_non_signaling_thread_ = true;
174 }
175 candidates_[transport_name].insert(candidates_[transport_name].end(),
176 candidates.begin(), candidates.end());
177 ++candidates_signal_count_;
178 }
179
jbauch555604a2016-04-26 03:13:22 -0700180 std::unique_ptr<rtc::Thread> worker_thread_; // Not used for most tests.
181 std::unique_ptr<TransportControllerForTest> transport_controller_;
deadbeefcbecd352015-09-23 11:50:27 -0700182
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
honghaiz1f429e32015-09-28 07:57:34 -0700200TEST_F(TransportControllerTest, TestSetIceConfig) {
deadbeefcbecd352015-09-23 11:50:27 -0700201 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
202 ASSERT_NE(nullptr, channel1);
203
honghaiz1f429e32015-09-28 07:57:34 -0700204 transport_controller_->SetIceConfig(CreateIceConfig(1000, true));
deadbeefcbecd352015-09-23 11:50:27 -0700205 EXPECT_EQ(1000, channel1->receiving_timeout());
honghaiz1f429e32015-09-28 07:57:34 -0700206 EXPECT_TRUE(channel1->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700207
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());
honghaiz1f429e32015-09-28 07:57:34 -0700212 EXPECT_TRUE(channel2->gather_continually());
deadbeefcbecd352015-09-23 11:50:27 -0700213}
214
215TEST_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
228TEST_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.
245TEST_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());
deadbeef1c206102016-05-27 13:34:37 -0700258
259 // Should be able to handle a second role conflict. The remote endpoint can
260 // change its role/tie-breaker when it does an ICE restart.
261 channel2->SignalRoleConflict(channel2);
262 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
263 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
deadbeefcbecd352015-09-23 11:50:27 -0700264}
265
266TEST_F(TransportControllerTest, TestGetSslRole) {
267 FakeTransportChannel* channel = CreateChannel("audio", 1);
268 ASSERT_NE(nullptr, channel);
269 ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT));
270 rtc::SSLRole role;
Taylor Brandstetterf475d362016-01-08 15:35:57 -0800271 EXPECT_FALSE(transport_controller_->GetSslRole("video", &role));
272 EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role));
deadbeefcbecd352015-09-23 11:50:27 -0700273 EXPECT_EQ(rtc::SSL_CLIENT, role);
274}
275
276TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
277 rtc::scoped_refptr<rtc::RTCCertificate> certificate1 =
jbauch555604a2016-04-26 03:13:22 -0700278 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800279 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700280 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 =
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("session2", rtc::KT_DEFAULT)));
deadbeefcbecd352015-09-23 11:50:27 -0700283 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;
284
285 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
286 ASSERT_NE(nullptr, channel1);
287
288 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
289 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
290 "audio", &returned_certificate));
291 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
292 returned_certificate->identity()->certificate().ToPEMString());
293
294 // Should fail if called for a nonexistant transport.
295 EXPECT_FALSE(transport_controller_->GetLocalCertificate(
296 "video", &returned_certificate));
297
298 // Test that identity stored in controller is applied to new channels.
299 FakeTransportChannel* channel2 = CreateChannel("video", 1);
300 ASSERT_NE(nullptr, channel2);
301 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
302 "video", &returned_certificate));
303 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
304 returned_certificate->identity()->certificate().ToPEMString());
305
306 // Shouldn't be able to change the identity once set.
307 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
308}
309
310TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
311 rtc::FakeSSLCertificate fake_certificate("fake_data");
deadbeefcbecd352015-09-23 11:50:27 -0700312
313 FakeTransportChannel* channel = CreateChannel("audio", 1);
314 ASSERT_NE(nullptr, channel);
315
316 channel->SetRemoteSSLCertificate(&fake_certificate);
jbauch555604a2016-04-26 03:13:22 -0700317 std::unique_ptr<rtc::SSLCertificate> returned_certificate =
kwibergb4d01c42016-04-06 05:15:06 -0700318 transport_controller_->GetRemoteSSLCertificate("audio");
319 EXPECT_TRUE(returned_certificate);
deadbeefcbecd352015-09-23 11:50:27 -0700320 EXPECT_EQ(fake_certificate.ToPEMString(),
321 returned_certificate->ToPEMString());
322
323 // Should fail if called for a nonexistant transport.
kwibergb4d01c42016-04-06 05:15:06 -0700324 EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate("video"));
deadbeefcbecd352015-09-23 11:50:27 -0700325}
326
327TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
328 FakeTransportChannel* channel = CreateChannel("audio", 1);
329 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800330 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
331 kIcePwd1, cricket::ICEMODE_FULL,
332 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700333 std::string err;
334 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
335 "audio", local_desc, cricket::CA_OFFER, &err));
336 // Check that ICE ufrag and pwd were propagated to channel.
337 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag());
338 EXPECT_EQ(kIcePwd1, channel->ice_pwd());
339 // After setting local description, we should be able to start gathering
340 // candidates.
341 transport_controller_->MaybeStartGathering();
342 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
343 EXPECT_EQ(1, gathering_state_signal_count_);
344}
345
346TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
347 FakeTransportChannel* channel = CreateChannel("audio", 1);
348 ASSERT_NE(nullptr, channel);
deadbeef46eed762016-01-28 13:24:37 -0800349 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
350 kIcePwd1, cricket::ICEMODE_FULL,
351 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700352 std::string err;
353 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
354 "audio", remote_desc, cricket::CA_OFFER, &err));
355 // Check that ICE ufrag and pwd were propagated to channel.
356 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag());
357 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd());
358}
359
360TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
361 FakeTransportChannel* channel = CreateChannel("audio", 1);
362 ASSERT_NE(nullptr, channel);
363 Candidates candidates;
364 candidates.push_back(CreateCandidate(1));
365 std::string err;
366 EXPECT_TRUE(
367 transport_controller_->AddRemoteCandidates("audio", candidates, &err));
368 EXPECT_EQ(1U, channel->remote_candidates().size());
369}
370
371TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
372 FakeTransportChannel* channel = CreateChannel("audio", 1);
373 ASSERT_NE(nullptr, channel);
374 // We expect to be ready for remote candidates only after local and remote
375 // descriptions are set.
376 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
377
378 std::string err;
deadbeef46eed762016-01-28 13:24:37 -0800379 TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
380 kIcePwd1, cricket::ICEMODE_FULL,
381 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700382 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
383 "audio", remote_desc, cricket::CA_OFFER, &err));
384 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
385
deadbeef46eed762016-01-28 13:24:37 -0800386 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
387 kIcePwd2, cricket::ICEMODE_FULL,
388 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700389 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
390 "audio", local_desc, cricket::CA_ANSWER, &err));
391 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio"));
392}
393
394TEST_F(TransportControllerTest, TestGetStats) {
395 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
396 ASSERT_NE(nullptr, channel1);
397 FakeTransportChannel* channel2 = CreateChannel("audio", 2);
398 ASSERT_NE(nullptr, channel2);
399 FakeTransportChannel* channel3 = CreateChannel("video", 1);
400 ASSERT_NE(nullptr, channel3);
401
402 TransportStats stats;
403 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
404 EXPECT_EQ("audio", stats.transport_name);
405 EXPECT_EQ(2U, stats.channel_stats.size());
406}
407
408// Test that transport gets destroyed when it has no more channels.
409TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
410 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
411 ASSERT_NE(nullptr, channel1);
412 FakeTransportChannel* channel2 = CreateChannel("audio", 1);
413 ASSERT_NE(nullptr, channel2);
414 ASSERT_EQ(channel1, channel2);
415 FakeTransportChannel* channel3 = CreateChannel("audio", 2);
416 ASSERT_NE(nullptr, channel3);
417
418 // Using GetStats to check if transport is destroyed from an outside class's
419 // perspective.
420 TransportStats stats;
421 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
422 DestroyChannel("audio", 2);
423 DestroyChannel("audio", 1);
424 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
425 DestroyChannel("audio", 1);
426 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats));
427}
428
429TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
430 // Need controlling ICE role to get in failed state.
431 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
432 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
433 ASSERT_NE(nullptr, channel1);
434 FakeTransportChannel* channel2 = CreateChannel("video", 1);
435 ASSERT_NE(nullptr, channel2);
436
437 // Should signal "failed" if any channel failed; channel is considered failed
438 // if it previously had a connection but now has none, and gathering is
439 // complete.
440 channel1->SetCandidatesGatheringComplete();
441 channel1->SetConnectionCount(1);
442 channel1->SetConnectionCount(0);
443 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
444 EXPECT_EQ(1, connection_state_signal_count_);
445}
446
447TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
448 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
449 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
450 ASSERT_NE(nullptr, channel1);
451 FakeTransportChannel* channel2 = CreateChannel("video", 1);
452 ASSERT_NE(nullptr, channel2);
453 FakeTransportChannel* channel3 = CreateChannel("video", 2);
454 ASSERT_NE(nullptr, channel3);
455
456 // First, have one channel connect, and another fail, to ensure that
457 // the first channel connecting didn't trigger a "connected" state signal.
458 // We should only get a signal when all are connected.
459 channel1->SetConnectionCount(2);
460 channel1->SetWritable(true);
461 channel3->SetCandidatesGatheringComplete();
462 channel3->SetConnectionCount(1);
463 channel3->SetConnectionCount(0);
464 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
465 // Signal count of 1 means that the only signal emitted was "failed".
466 EXPECT_EQ(1, connection_state_signal_count_);
467
468 // Destroy the failed channel to return to "connecting" state.
469 DestroyChannel("video", 2);
470 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
471 kTimeout);
472 EXPECT_EQ(2, connection_state_signal_count_);
473
474 // Make the remaining channel reach a connected state.
475 channel2->SetConnectionCount(2);
476 channel2->SetWritable(true);
477 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
478 EXPECT_EQ(3, connection_state_signal_count_);
479}
480
481TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
482 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
483 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
484 ASSERT_NE(nullptr, channel1);
485 FakeTransportChannel* channel2 = CreateChannel("video", 1);
486 ASSERT_NE(nullptr, channel2);
487 FakeTransportChannel* channel3 = CreateChannel("video", 2);
488 ASSERT_NE(nullptr, channel3);
489
490 // Similar to above test, but we're now reaching the completed state, which
491 // means only one connection per FakeTransportChannel.
492 channel1->SetCandidatesGatheringComplete();
493 channel1->SetConnectionCount(1);
494 channel1->SetWritable(true);
495 channel3->SetCandidatesGatheringComplete();
496 channel3->SetConnectionCount(1);
497 channel3->SetConnectionCount(0);
498 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
499 // Signal count of 1 means that the only signal emitted was "failed".
500 EXPECT_EQ(1, connection_state_signal_count_);
501
502 // Destroy the failed channel to return to "connecting" state.
503 DestroyChannel("video", 2);
504 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
505 kTimeout);
506 EXPECT_EQ(2, connection_state_signal_count_);
507
508 // Make the remaining channel reach a connected state.
509 channel2->SetCandidatesGatheringComplete();
510 channel2->SetConnectionCount(2);
511 channel2->SetWritable(true);
512 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
513 EXPECT_EQ(3, connection_state_signal_count_);
514
515 // Finally, transition to completed state.
516 channel2->SetConnectionCount(1);
517 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
518 EXPECT_EQ(4, connection_state_signal_count_);
519}
520
521// Make sure that if we're "connected" and remove a transport, we stay in the
522// "connected" state.
523TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
524 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
525 ASSERT_NE(nullptr, channel1);
526 FakeTransportChannel* channel2 = CreateChannel("video", 1);
527 ASSERT_NE(nullptr, channel2);
528
529 channel1->SetCandidatesGatheringComplete();
530 channel1->SetConnectionCount(2);
531 channel1->SetWritable(true);
532 channel2->SetCandidatesGatheringComplete();
533 channel2->SetConnectionCount(2);
534 channel2->SetWritable(true);
535 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
536 EXPECT_EQ(1, connection_state_signal_count_);
537
538 // Destroy one channel, then "complete" the other one, so we reach
539 // a known state.
540 DestroyChannel("video", 1);
541 channel1->SetConnectionCount(1);
542 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
543 // Signal count of 2 means the deletion didn't cause any unexpected signals
544 EXPECT_EQ(2, connection_state_signal_count_);
545}
546
547// If we destroy the last/only transport, we should simply transition to
548// "connecting".
549TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
550 FakeTransportChannel* channel = CreateChannel("audio", 1);
551 ASSERT_NE(nullptr, channel);
552
553 channel->SetCandidatesGatheringComplete();
554 channel->SetConnectionCount(2);
555 channel->SetWritable(true);
556 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
557 EXPECT_EQ(1, connection_state_signal_count_);
558
559 DestroyChannel("audio", 1);
560 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
561 kTimeout);
562 // Signal count of 2 means the deletion didn't cause any unexpected signals
563 EXPECT_EQ(2, connection_state_signal_count_);
564}
565
566TEST_F(TransportControllerTest, TestSignalReceiving) {
567 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
568 ASSERT_NE(nullptr, channel1);
569 FakeTransportChannel* channel2 = CreateChannel("video", 1);
570 ASSERT_NE(nullptr, channel2);
571
572 // Should signal receiving as soon as any channel is receiving.
573 channel1->SetReceiving(true);
574 EXPECT_TRUE_WAIT(receiving_, kTimeout);
575 EXPECT_EQ(1, receiving_signal_count_);
576
577 channel2->SetReceiving(true);
578 channel1->SetReceiving(false);
579 channel2->SetReceiving(false);
580 EXPECT_TRUE_WAIT(!receiving_, kTimeout);
581 EXPECT_EQ(2, receiving_signal_count_);
582}
583
584TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
585 FakeTransportChannel* channel = CreateChannel("audio", 1);
586 ASSERT_NE(nullptr, channel);
587 channel->Connect();
588 channel->MaybeStartGathering();
589 // Should be in the gathering state as soon as any transport starts gathering.
590 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
591 EXPECT_EQ(1, gathering_state_signal_count_);
592}
593
594TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
595 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
596 ASSERT_NE(nullptr, channel1);
597 FakeTransportChannel* channel2 = CreateChannel("video", 1);
598 ASSERT_NE(nullptr, channel2);
599 FakeTransportChannel* channel3 = CreateChannel("data", 1);
600 ASSERT_NE(nullptr, channel3);
601
602 channel3->Connect();
603 channel3->MaybeStartGathering();
604 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
605 EXPECT_EQ(1, gathering_state_signal_count_);
606
607 // Have one channel finish gathering, then destroy it, to make sure gathering
608 // completion wasn't signalled if only one transport finished gathering.
609 channel3->SetCandidatesGatheringComplete();
610 DestroyChannel("data", 1);
611 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout);
612 EXPECT_EQ(2, gathering_state_signal_count_);
613
614 // Make remaining channels start and then finish gathering.
615 channel1->Connect();
616 channel1->MaybeStartGathering();
617 channel2->Connect();
618 channel2->MaybeStartGathering();
619 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
620 EXPECT_EQ(3, gathering_state_signal_count_);
621
622 channel1->SetCandidatesGatheringComplete();
623 channel2->SetCandidatesGatheringComplete();
624 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
625 EXPECT_EQ(4, gathering_state_signal_count_);
626}
627
628// Test that when the last transport that hasn't finished connecting and/or
629// gathering is destroyed, the aggregate state jumps to "completed". This can
630// happen if, for example, we have an audio and video transport, the audio
631// transport completes, then we start bundling video on the audio transport.
632TEST_F(TransportControllerTest,
633 TestSignalingWhenLastIncompleteTransportDestroyed) {
634 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
635 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
636 ASSERT_NE(nullptr, channel1);
637 FakeTransportChannel* channel2 = CreateChannel("video", 1);
638 ASSERT_NE(nullptr, channel2);
639
640 channel1->SetCandidatesGatheringComplete();
641 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
642 EXPECT_EQ(1, gathering_state_signal_count_);
643
644 channel1->SetConnectionCount(1);
645 channel1->SetWritable(true);
646 DestroyChannel("video", 1);
647 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
648 EXPECT_EQ(1, connection_state_signal_count_);
649 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
650 EXPECT_EQ(2, gathering_state_signal_count_);
651}
652
653TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
654 FakeTransportChannel* channel = CreateChannel("audio", 1);
655 ASSERT_NE(nullptr, channel);
656
657 // Transport won't signal candidates until it has a local description.
deadbeef46eed762016-01-28 13:24:37 -0800658 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
659 kIcePwd1, cricket::ICEMODE_FULL,
660 cricket::CONNECTIONROLE_ACTPASS, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700661 std::string err;
662 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
663 "audio", local_desc, cricket::CA_OFFER, &err));
664 transport_controller_->MaybeStartGathering();
665
666 channel->SignalCandidateGathered(channel, CreateCandidate(1));
667 EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout);
668 EXPECT_EQ(1U, candidates_["audio"].size());
669}
670
671TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) {
672 CreateTransportControllerWithWorkerThread();
673 CreateChannelsAndCompleteConnectionOnWorkerThread();
674
675 // connecting --> connected --> completed
676 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
677 EXPECT_EQ(2, connection_state_signal_count_);
678
679 EXPECT_TRUE_WAIT(receiving_, kTimeout);
680 EXPECT_EQ(1, receiving_signal_count_);
681
682 // new --> gathering --> complete
683 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
684 EXPECT_EQ(2, gathering_state_signal_count_);
685
686 EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout);
687 EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout);
688 EXPECT_EQ(2, candidates_signal_count_);
689
690 EXPECT_TRUE(!signaled_on_non_signaling_thread_);
691}