OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <map> | |
12 | |
13 #include "webrtc/base/fakesslidentity.h" | |
14 #include "webrtc/base/gunit.h" | |
15 #include "webrtc/base/helpers.h" | |
16 #include "webrtc/base/scoped_ptr.h" | |
17 #include "webrtc/base/sslidentity.h" | |
18 #include "webrtc/base/thread.h" | |
19 #include "webrtc/p2p/base/dtlstransportchannel.h" | |
20 #include "webrtc/p2p/base/faketransportcontroller.h" | |
21 #include "webrtc/p2p/base/p2ptransportchannel.h" | |
22 #include "webrtc/p2p/base/portallocator.h" | |
23 #include "webrtc/p2p/base/transportcontroller.h" | |
24 #include "webrtc/p2p/client/fakeportallocator.h" | |
25 | |
26 static const int kTimeout = 100; | |
27 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; | |
28 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; | |
29 static const char kIceUfrag2[] = "TESTICEUFRAG0002"; | |
30 static const char kIcePwd2[] = "TESTICEPWD00000000000002"; | |
31 | |
32 using cricket::Candidate; | |
33 using cricket::Candidates; | |
34 using cricket::FakeTransportChannel; | |
35 using cricket::FakeTransportController; | |
36 using cricket::IceConnectionState; | |
37 using cricket::IceGatheringState; | |
38 using cricket::TransportChannel; | |
39 using cricket::TransportController; | |
40 using cricket::TransportDescription; | |
41 using cricket::TransportStats; | |
42 | |
43 // Only subclassing from FakeTransportController because currently that's the | |
44 // only way to have a TransportController with fake TransportChannels. | |
45 // | |
46 // TODO(deadbeef): Change this once the Transport/TransportChannel class | |
47 // heirarchy is cleaned up, and we can pass a "TransportChannelFactory" or | |
48 // something similar into TransportController. | |
49 typedef FakeTransportController TransportControllerForTest; | |
50 | |
51 class TransportControllerTest : public testing::Test, | |
52 public sigslot::has_slots<> { | |
53 public: | |
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 = | |
84 transport_controller_->CreateTransportChannel_w(content, component); | |
85 return static_cast<FakeTransportChannel*>(channel); | |
86 } | |
87 | |
88 void DestroyChannel(const std::string& content, int component) { | |
89 transport_controller_->DestroyTransportChannel_w(content, component); | |
90 } | |
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 | |
114 TransportDescription local_desc( | |
115 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
116 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
117 std::string err; | |
118 transport_controller_->SetLocalTransportDescription( | |
119 "audio", local_desc, cricket::CA_OFFER, &err); | |
120 transport_controller_->SetLocalTransportDescription( | |
121 "video", local_desc, cricket::CA_OFFER, &err); | |
122 transport_controller_->MaybeStartGathering(); | |
123 channel1->SignalCandidateGathered(channel1, CreateCandidate(1)); | |
124 channel2->SignalCandidateGathered(channel2, CreateCandidate(1)); | |
125 channel1->SetCandidatesGatheringComplete(); | |
126 channel2->SetCandidatesGatheringComplete(); | |
127 channel1->SetConnectionCount(2); | |
128 channel2->SetConnectionCount(2); | |
129 channel1->SetReceiving(true); | |
130 channel2->SetReceiving(true); | |
131 channel1->SetWritable(true); | |
132 channel2->SetWritable(true); | |
133 channel1->SetConnectionCount(1); | |
134 channel2->SetConnectionCount(1); | |
135 } | |
136 | |
137 protected: | |
138 void OnConnectionState(IceConnectionState state) { | |
139 if (!signaling_thread_->IsCurrent()) { | |
140 signaled_on_non_signaling_thread_ = true; | |
141 } | |
142 connection_state_ = state; | |
143 ++connection_state_signal_count_; | |
144 } | |
145 | |
146 void OnReceiving(bool receiving) { | |
147 if (!signaling_thread_->IsCurrent()) { | |
148 signaled_on_non_signaling_thread_ = true; | |
149 } | |
150 receiving_ = receiving; | |
151 ++receiving_signal_count_; | |
152 } | |
153 | |
154 void OnGatheringState(IceGatheringState state) { | |
155 if (!signaling_thread_->IsCurrent()) { | |
156 signaled_on_non_signaling_thread_ = true; | |
157 } | |
158 gathering_state_ = state; | |
159 ++gathering_state_signal_count_; | |
160 } | |
161 | |
162 void OnCandidatesGathered(const std::string& transport_name, | |
163 const Candidates& candidates) { | |
164 if (!signaling_thread_->IsCurrent()) { | |
165 signaled_on_non_signaling_thread_ = true; | |
166 } | |
167 candidates_[transport_name].insert(candidates_[transport_name].end(), | |
168 candidates.begin(), candidates.end()); | |
169 ++candidates_signal_count_; | |
170 } | |
171 | |
172 rtc::scoped_ptr<rtc::Thread> worker_thread_; // Not used for most tests. | |
173 rtc::scoped_ptr<TransportControllerForTest> transport_controller_; | |
174 | |
175 // Information received from signals from transport controller. | |
176 IceConnectionState connection_state_ = cricket::kIceConnectionConnecting; | |
177 bool receiving_ = false; | |
178 IceGatheringState gathering_state_ = cricket::kIceGatheringNew; | |
179 // transport_name => candidates | |
180 std::map<std::string, Candidates> candidates_; | |
181 // Counts of each signal emitted. | |
182 int connection_state_signal_count_ = 0; | |
183 int receiving_signal_count_ = 0; | |
184 int gathering_state_signal_count_ = 0; | |
185 int candidates_signal_count_ = 0; | |
186 | |
187 // Used to make sure signals only come on signaling thread. | |
188 rtc::Thread* const signaling_thread_ = nullptr; | |
189 bool signaled_on_non_signaling_thread_ = false; | |
190 }; | |
191 | |
192 TEST_F(TransportControllerTest, TestSetIceReceivingTimeout) { | |
193 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
194 ASSERT_NE(nullptr, channel1); | |
195 | |
196 transport_controller_->SetIceConnectionReceivingTimeout(1000); | |
197 EXPECT_EQ(1000, channel1->receiving_timeout()); | |
198 | |
199 // Test that value stored in controller is applied to new channels. | |
200 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
201 ASSERT_NE(nullptr, channel2); | |
202 EXPECT_EQ(1000, channel2->receiving_timeout()); | |
203 } | |
204 | |
205 TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) { | |
206 EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion( | |
207 rtc::SSL_PROTOCOL_DTLS_12)); | |
208 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
209 | |
210 ASSERT_NE(nullptr, channel); | |
211 EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, channel->ssl_max_protocol_version()); | |
212 | |
213 // Setting max version after transport is created should fail. | |
214 EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion( | |
215 rtc::SSL_PROTOCOL_DTLS_10)); | |
216 } | |
217 | |
218 TEST_F(TransportControllerTest, TestSetIceRole) { | |
219 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
220 ASSERT_NE(nullptr, channel1); | |
221 | |
222 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
223 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); | |
224 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); | |
225 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); | |
226 | |
227 // Test that value stored in controller is applied to new channels. | |
228 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
229 ASSERT_NE(nullptr, channel2); | |
230 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole()); | |
231 } | |
232 | |
233 // Test that when one channel encounters a role conflict, the ICE role is | |
234 // swapped on every channel. | |
235 TEST_F(TransportControllerTest, TestIceRoleConflict) { | |
236 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
237 ASSERT_NE(nullptr, channel1); | |
238 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
239 ASSERT_NE(nullptr, channel2); | |
240 | |
241 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
242 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); | |
243 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole()); | |
244 | |
245 channel1->SignalRoleConflict(channel1); | |
246 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); | |
247 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole()); | |
248 } | |
249 | |
250 TEST_F(TransportControllerTest, TestGetSslRole) { | |
251 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
252 ASSERT_NE(nullptr, channel); | |
253 ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT)); | |
254 rtc::SSLRole role; | |
255 EXPECT_TRUE(transport_controller_->GetSslRole(&role)); | |
256 EXPECT_EQ(rtc::SSL_CLIENT, role); | |
257 } | |
258 | |
259 TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) { | |
260 rtc::scoped_refptr<rtc::RTCCertificate> certificate1 = | |
261 rtc::RTCCertificate::Create( | |
262 rtc::scoped_ptr<rtc::SSLIdentity>( | |
263 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)) | |
264 .Pass()); | |
265 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 = | |
266 rtc::RTCCertificate::Create( | |
267 rtc::scoped_ptr<rtc::SSLIdentity>( | |
268 rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)) | |
269 .Pass()); | |
270 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate; | |
271 | |
272 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
273 ASSERT_NE(nullptr, channel1); | |
274 | |
275 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1)); | |
276 EXPECT_TRUE(transport_controller_->GetLocalCertificate( | |
277 "audio", &returned_certificate)); | |
278 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), | |
279 returned_certificate->identity()->certificate().ToPEMString()); | |
280 | |
281 // Should fail if called for a nonexistant transport. | |
282 EXPECT_FALSE(transport_controller_->GetLocalCertificate( | |
283 "video", &returned_certificate)); | |
284 | |
285 // Test that identity stored in controller is applied to new channels. | |
286 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
287 ASSERT_NE(nullptr, channel2); | |
288 EXPECT_TRUE(transport_controller_->GetLocalCertificate( | |
289 "video", &returned_certificate)); | |
290 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), | |
291 returned_certificate->identity()->certificate().ToPEMString()); | |
292 | |
293 // Shouldn't be able to change the identity once set. | |
294 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2)); | |
295 } | |
296 | |
297 TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) { | |
298 rtc::FakeSSLCertificate fake_certificate("fake_data"); | |
299 rtc::scoped_ptr<rtc::SSLCertificate> returned_certificate; | |
300 | |
301 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
302 ASSERT_NE(nullptr, channel); | |
303 | |
304 channel->SetRemoteSSLCertificate(&fake_certificate); | |
305 EXPECT_TRUE(transport_controller_->GetRemoteSSLCertificate( | |
306 "audio", returned_certificate.accept())); | |
307 EXPECT_EQ(fake_certificate.ToPEMString(), | |
308 returned_certificate->ToPEMString()); | |
309 | |
310 // Should fail if called for a nonexistant transport. | |
311 EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate( | |
312 "video", returned_certificate.accept())); | |
313 } | |
314 | |
315 TEST_F(TransportControllerTest, TestSetLocalTransportDescription) { | |
316 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
317 ASSERT_NE(nullptr, channel); | |
318 TransportDescription local_desc( | |
319 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
320 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
321 std::string err; | |
322 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( | |
323 "audio", local_desc, cricket::CA_OFFER, &err)); | |
324 // Check that ICE ufrag and pwd were propagated to channel. | |
325 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag()); | |
326 EXPECT_EQ(kIcePwd1, channel->ice_pwd()); | |
327 // After setting local description, we should be able to start gathering | |
328 // candidates. | |
329 transport_controller_->MaybeStartGathering(); | |
330 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); | |
331 EXPECT_EQ(1, gathering_state_signal_count_); | |
332 } | |
333 | |
334 TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) { | |
335 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
336 ASSERT_NE(nullptr, channel); | |
337 TransportDescription remote_desc( | |
338 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
339 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
340 std::string err; | |
341 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( | |
342 "audio", remote_desc, cricket::CA_OFFER, &err)); | |
343 // Check that ICE ufrag and pwd were propagated to channel. | |
344 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag()); | |
345 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd()); | |
346 } | |
347 | |
348 TEST_F(TransportControllerTest, TestAddRemoteCandidates) { | |
349 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
350 ASSERT_NE(nullptr, channel); | |
351 Candidates candidates; | |
352 candidates.push_back(CreateCandidate(1)); | |
353 std::string err; | |
354 EXPECT_TRUE( | |
355 transport_controller_->AddRemoteCandidates("audio", candidates, &err)); | |
356 EXPECT_EQ(1U, channel->remote_candidates().size()); | |
357 } | |
358 | |
359 TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) { | |
360 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
361 ASSERT_NE(nullptr, channel); | |
362 // We expect to be ready for remote candidates only after local and remote | |
363 // descriptions are set. | |
364 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); | |
365 | |
366 std::string err; | |
367 TransportDescription remote_desc( | |
368 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
369 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
370 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( | |
371 "audio", remote_desc, cricket::CA_OFFER, &err)); | |
372 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); | |
373 | |
374 TransportDescription local_desc( | |
375 std::vector<std::string>(), kIceUfrag2, kIcePwd2, cricket::ICEMODE_FULL, | |
376 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
377 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( | |
378 "audio", local_desc, cricket::CA_ANSWER, &err)); | |
379 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio")); | |
380 } | |
381 | |
382 TEST_F(TransportControllerTest, TestGetStats) { | |
383 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
384 ASSERT_NE(nullptr, channel1); | |
385 FakeTransportChannel* channel2 = CreateChannel("audio", 2); | |
386 ASSERT_NE(nullptr, channel2); | |
387 FakeTransportChannel* channel3 = CreateChannel("video", 1); | |
388 ASSERT_NE(nullptr, channel3); | |
389 | |
390 TransportStats stats; | |
391 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); | |
392 EXPECT_EQ("audio", stats.transport_name); | |
393 EXPECT_EQ(2U, stats.channel_stats.size()); | |
394 } | |
395 | |
396 // Test that transport gets destroyed when it has no more channels. | |
397 TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) { | |
398 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
399 ASSERT_NE(nullptr, channel1); | |
400 FakeTransportChannel* channel2 = CreateChannel("audio", 1); | |
401 ASSERT_NE(nullptr, channel2); | |
402 ASSERT_EQ(channel1, channel2); | |
403 FakeTransportChannel* channel3 = CreateChannel("audio", 2); | |
404 ASSERT_NE(nullptr, channel3); | |
405 | |
406 // Using GetStats to check if transport is destroyed from an outside class's | |
407 // perspective. | |
408 TransportStats stats; | |
409 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); | |
410 DestroyChannel("audio", 2); | |
411 DestroyChannel("audio", 1); | |
412 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); | |
413 DestroyChannel("audio", 1); | |
414 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats)); | |
415 } | |
416 | |
417 TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) { | |
418 // Need controlling ICE role to get in failed state. | |
419 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
420 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
421 ASSERT_NE(nullptr, channel1); | |
422 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
423 ASSERT_NE(nullptr, channel2); | |
424 | |
425 // Should signal "failed" if any channel failed; channel is considered failed | |
426 // if it previously had a connection but now has none, and gathering is | |
427 // complete. | |
428 channel1->SetCandidatesGatheringComplete(); | |
429 channel1->SetConnectionCount(1); | |
430 channel1->SetConnectionCount(0); | |
431 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); | |
432 EXPECT_EQ(1, connection_state_signal_count_); | |
433 } | |
434 | |
435 TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) { | |
436 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
437 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
438 ASSERT_NE(nullptr, channel1); | |
439 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
440 ASSERT_NE(nullptr, channel2); | |
441 FakeTransportChannel* channel3 = CreateChannel("video", 2); | |
442 ASSERT_NE(nullptr, channel3); | |
443 | |
444 // First, have one channel connect, and another fail, to ensure that | |
445 // the first channel connecting didn't trigger a "connected" state signal. | |
446 // We should only get a signal when all are connected. | |
447 channel1->SetConnectionCount(2); | |
448 channel1->SetWritable(true); | |
449 channel3->SetCandidatesGatheringComplete(); | |
450 channel3->SetConnectionCount(1); | |
451 channel3->SetConnectionCount(0); | |
452 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); | |
453 // Signal count of 1 means that the only signal emitted was "failed". | |
454 EXPECT_EQ(1, connection_state_signal_count_); | |
455 | |
456 // Destroy the failed channel to return to "connecting" state. | |
457 DestroyChannel("video", 2); | |
458 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, | |
459 kTimeout); | |
460 EXPECT_EQ(2, connection_state_signal_count_); | |
461 | |
462 // Make the remaining channel reach a connected state. | |
463 channel2->SetConnectionCount(2); | |
464 channel2->SetWritable(true); | |
465 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); | |
466 EXPECT_EQ(3, connection_state_signal_count_); | |
467 } | |
468 | |
469 TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) { | |
470 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
471 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
472 ASSERT_NE(nullptr, channel1); | |
473 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
474 ASSERT_NE(nullptr, channel2); | |
475 FakeTransportChannel* channel3 = CreateChannel("video", 2); | |
476 ASSERT_NE(nullptr, channel3); | |
477 | |
478 // Similar to above test, but we're now reaching the completed state, which | |
479 // means only one connection per FakeTransportChannel. | |
480 channel1->SetCandidatesGatheringComplete(); | |
481 channel1->SetConnectionCount(1); | |
482 channel1->SetWritable(true); | |
483 channel3->SetCandidatesGatheringComplete(); | |
484 channel3->SetConnectionCount(1); | |
485 channel3->SetConnectionCount(0); | |
486 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout); | |
487 // Signal count of 1 means that the only signal emitted was "failed". | |
488 EXPECT_EQ(1, connection_state_signal_count_); | |
489 | |
490 // Destroy the failed channel to return to "connecting" state. | |
491 DestroyChannel("video", 2); | |
492 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, | |
493 kTimeout); | |
494 EXPECT_EQ(2, connection_state_signal_count_); | |
495 | |
496 // Make the remaining channel reach a connected state. | |
497 channel2->SetCandidatesGatheringComplete(); | |
498 channel2->SetConnectionCount(2); | |
499 channel2->SetWritable(true); | |
500 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); | |
501 EXPECT_EQ(3, connection_state_signal_count_); | |
502 | |
503 // Finally, transition to completed state. | |
504 channel2->SetConnectionCount(1); | |
505 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); | |
506 EXPECT_EQ(4, connection_state_signal_count_); | |
507 } | |
508 | |
509 // Make sure that if we're "connected" and remove a transport, we stay in the | |
510 // "connected" state. | |
511 TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) { | |
512 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
513 ASSERT_NE(nullptr, channel1); | |
514 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
515 ASSERT_NE(nullptr, channel2); | |
516 | |
517 channel1->SetCandidatesGatheringComplete(); | |
518 channel1->SetConnectionCount(2); | |
519 channel1->SetWritable(true); | |
520 channel2->SetCandidatesGatheringComplete(); | |
521 channel2->SetConnectionCount(2); | |
522 channel2->SetWritable(true); | |
523 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); | |
524 EXPECT_EQ(1, connection_state_signal_count_); | |
525 | |
526 // Destroy one channel, then "complete" the other one, so we reach | |
527 // a known state. | |
528 DestroyChannel("video", 1); | |
529 channel1->SetConnectionCount(1); | |
530 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); | |
531 // Signal count of 2 means the deletion didn't cause any unexpected signals | |
532 EXPECT_EQ(2, connection_state_signal_count_); | |
533 } | |
534 | |
535 // If we destroy the last/only transport, we should simply transition to | |
536 // "connecting". | |
537 TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) { | |
538 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
539 ASSERT_NE(nullptr, channel); | |
540 | |
541 channel->SetCandidatesGatheringComplete(); | |
542 channel->SetConnectionCount(2); | |
543 channel->SetWritable(true); | |
544 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout); | |
545 EXPECT_EQ(1, connection_state_signal_count_); | |
546 | |
547 DestroyChannel("audio", 1); | |
548 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_, | |
549 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 TEST_F(TransportControllerTest, TestSignalReceiving) { | |
555 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
556 ASSERT_NE(nullptr, channel1); | |
557 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
558 ASSERT_NE(nullptr, channel2); | |
559 | |
560 // Should signal receiving as soon as any channel is receiving. | |
561 channel1->SetReceiving(true); | |
562 EXPECT_TRUE_WAIT(receiving_, kTimeout); | |
563 EXPECT_EQ(1, receiving_signal_count_); | |
564 | |
565 channel2->SetReceiving(true); | |
566 channel1->SetReceiving(false); | |
567 channel2->SetReceiving(false); | |
568 EXPECT_TRUE_WAIT(!receiving_, kTimeout); | |
569 EXPECT_EQ(2, receiving_signal_count_); | |
570 } | |
571 | |
572 TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) { | |
573 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
574 ASSERT_NE(nullptr, channel); | |
575 channel->Connect(); | |
576 channel->MaybeStartGathering(); | |
577 // Should be in the gathering state as soon as any transport starts gathering. | |
578 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); | |
579 EXPECT_EQ(1, gathering_state_signal_count_); | |
580 } | |
581 | |
582 TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) { | |
583 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
584 ASSERT_NE(nullptr, channel1); | |
585 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
586 ASSERT_NE(nullptr, channel2); | |
587 FakeTransportChannel* channel3 = CreateChannel("data", 1); | |
588 ASSERT_NE(nullptr, channel3); | |
589 | |
590 channel3->Connect(); | |
591 channel3->MaybeStartGathering(); | |
592 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); | |
593 EXPECT_EQ(1, gathering_state_signal_count_); | |
594 | |
595 // Have one channel finish gathering, then destroy it, to make sure gathering | |
596 // completion wasn't signalled if only one transport finished gathering. | |
597 channel3->SetCandidatesGatheringComplete(); | |
598 DestroyChannel("data", 1); | |
599 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout); | |
600 EXPECT_EQ(2, gathering_state_signal_count_); | |
601 | |
602 // Make remaining channels start and then finish gathering. | |
603 channel1->Connect(); | |
604 channel1->MaybeStartGathering(); | |
605 channel2->Connect(); | |
606 channel2->MaybeStartGathering(); | |
607 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); | |
608 EXPECT_EQ(3, gathering_state_signal_count_); | |
609 | |
610 channel1->SetCandidatesGatheringComplete(); | |
611 channel2->SetCandidatesGatheringComplete(); | |
612 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); | |
613 EXPECT_EQ(4, gathering_state_signal_count_); | |
614 } | |
615 | |
616 // Test that when the last transport that hasn't finished connecting and/or | |
617 // gathering is destroyed, the aggregate state jumps to "completed". This can | |
618 // happen if, for example, we have an audio and video transport, the audio | |
619 // transport completes, then we start bundling video on the audio transport. | |
620 TEST_F(TransportControllerTest, | |
621 TestSignalingWhenLastIncompleteTransportDestroyed) { | |
622 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | |
623 FakeTransportChannel* channel1 = CreateChannel("audio", 1); | |
624 ASSERT_NE(nullptr, channel1); | |
625 FakeTransportChannel* channel2 = CreateChannel("video", 1); | |
626 ASSERT_NE(nullptr, channel2); | |
627 | |
628 channel1->SetCandidatesGatheringComplete(); | |
629 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout); | |
630 EXPECT_EQ(1, gathering_state_signal_count_); | |
631 | |
632 channel1->SetConnectionCount(1); | |
633 channel1->SetWritable(true); | |
634 DestroyChannel("video", 1); | |
635 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); | |
636 EXPECT_EQ(1, connection_state_signal_count_); | |
637 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); | |
638 EXPECT_EQ(2, gathering_state_signal_count_); | |
639 } | |
640 | |
641 TEST_F(TransportControllerTest, TestSignalCandidatesGathered) { | |
642 FakeTransportChannel* channel = CreateChannel("audio", 1); | |
643 ASSERT_NE(nullptr, channel); | |
644 | |
645 // Transport won't signal candidates until it has a local description. | |
646 TransportDescription local_desc( | |
647 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
648 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates()); | |
649 std::string err; | |
650 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( | |
651 "audio", local_desc, cricket::CA_OFFER, &err)); | |
652 transport_controller_->MaybeStartGathering(); | |
653 | |
654 channel->SignalCandidateGathered(channel, CreateCandidate(1)); | |
655 EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout); | |
656 EXPECT_EQ(1U, candidates_["audio"].size()); | |
657 } | |
658 | |
659 TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) { | |
660 CreateTransportControllerWithWorkerThread(); | |
661 CreateChannelsAndCompleteConnectionOnWorkerThread(); | |
662 | |
663 // connecting --> connected --> completed | |
664 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout); | |
665 EXPECT_EQ(2, connection_state_signal_count_); | |
666 | |
667 EXPECT_TRUE_WAIT(receiving_, kTimeout); | |
668 EXPECT_EQ(1, receiving_signal_count_); | |
669 | |
670 // new --> gathering --> complete | |
671 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout); | |
672 EXPECT_EQ(2, gathering_state_signal_count_); | |
673 | |
674 EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout); | |
675 EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout); | |
676 EXPECT_EQ(2, candidates_signal_count_); | |
677 | |
678 EXPECT_TRUE(!signaled_on_non_signaling_thread_); | |
679 } | |
OLD | NEW |