Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: webrtc/p2p/base/transportcontroller_unittest.cc

Issue 1246913005: TransportController refactoring (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Merging again Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/base/transportchannelproxy.h"
25 #include "webrtc/p2p/client/fakeportallocator.h"
26
27 static const int kTimeout = 100;
28 static const char kIceUfrag1[] = "TESTICEUFRAG0001";
29 static const char kIcePwd1[] = "TESTICEPWD00000000000001";
30 static const char kIceUfrag2[] = "TESTICEUFRAG0002";
31 static const char kIcePwd2[] = "TESTICEPWD00000000000002";
32
33 using cricket::Candidate;
34 using cricket::Candidates;
35 using cricket::FakeTransportChannel;
36 using cricket::FakeTransportController;
37 using cricket::IceConnectionState;
38 using cricket::IceGatheringState;
39 using cricket::TransportChannel;
40 using cricket::TransportController;
41 using cricket::TransportDescription;
42 using cricket::TransportStats;
43
44 // Only subclassing from FakeTransportController because currently that's the
45 // only way to have a TransportController with fake TransportChannels.
46 //
47 // TODO(deadbeef): Change this once the Transport/TransportChannel class
48 // heirarchy is cleaned up, and we can pass a "TransportChannelFactory" or
49 // something similar into TransportController.
50 typedef FakeTransportController TransportControllerForTest;
51
52 class TransportControllerTest : public testing::Test,
53 public sigslot::has_slots<> {
54 public:
55 TransportControllerTest()
56 : transport_controller_(new TransportControllerForTest()),
57 signaling_thread_(rtc::Thread::Current()) {
58 ConnectTransportControllerSignals();
59 }
60
61 void CreateTransportControllerWithWorkerThread() {
62 if (!worker_thread_) {
63 worker_thread_.reset(new rtc::Thread());
64 worker_thread_->Start();
65 }
66 transport_controller_.reset(
67 new TransportControllerForTest(worker_thread_.get()));
68 ConnectTransportControllerSignals();
69 }
70
71 void ConnectTransportControllerSignals() {
72 transport_controller_->SignalConnectionState.connect(
73 this, &TransportControllerTest::OnConnectionState);
74 transport_controller_->SignalReceiving.connect(
75 this, &TransportControllerTest::OnReceiving);
76 transport_controller_->SignalGatheringState.connect(
77 this, &TransportControllerTest::OnGatheringState);
78 transport_controller_->SignalCandidatesGathered.connect(
79 this, &TransportControllerTest::OnCandidatesGathered);
80 }
81
82 FakeTransportChannel* CreateChannel(const std::string& content,
83 int component) {
84 TransportChannel* channel =
85 transport_controller_->CreateTransportChannel_w(content, component);
86 return static_cast<FakeTransportChannel*>(channel);
87 }
88
89 void DestroyChannel(const std::string& content, int component) {
90 transport_controller_->DestroyTransportChannel_w(content, component);
91 }
92
93 Candidate CreateCandidate(int component) {
94 Candidate c;
95 c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
96 c.set_component(1);
97 c.set_protocol(cricket::UDP_PROTOCOL_NAME);
98 c.set_priority(1);
99 return c;
100 }
101
102 // Used for thread hopping test
103 void CreateChannelsAndCompleteConnectionOnWorkerThread() {
104 worker_thread_->Invoke<void>(rtc::Bind(
105 &TransportControllerTest::CreateChannelsAndCompleteConnection_w, this));
106 }
107
108 void CreateChannelsAndCompleteConnection_w() {
109 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
110 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
111 ASSERT_NE(nullptr, channel1);
112 FakeTransportChannel* channel2 = CreateChannel("video", 1);
113 ASSERT_NE(nullptr, channel2);
114
115 TransportDescription local_desc(
116 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
117 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
118 std::string err;
119 transport_controller_->SetLocalTransportDescription(
120 "audio", local_desc, cricket::CA_OFFER, &err);
121 transport_controller_->SetLocalTransportDescription(
122 "video", local_desc, cricket::CA_OFFER, &err);
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)).Pass());
264 rtc::scoped_refptr<rtc::RTCCertificate> certificate2 =
265 rtc::RTCCertificate::Create(
266 rtc::scoped_ptr<rtc::SSLIdentity>(
267 rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)).Pass());
268 rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;
269
270 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
271 ASSERT_NE(nullptr, channel1);
272
273 EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
274 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
275 "audio", &returned_certificate));
276 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
277 returned_certificate->identity()->certificate().ToPEMString());
278
279 // Should fail if called for a nonexistant transport.
280 EXPECT_FALSE(transport_controller_->GetLocalCertificate(
281 "video", &returned_certificate));
282
283 // Test that identity stored in controller is applied to new channels.
284 FakeTransportChannel* channel2 = CreateChannel("video", 1);
285 ASSERT_NE(nullptr, channel2);
286 EXPECT_TRUE(transport_controller_->GetLocalCertificate(
287 "video", &returned_certificate));
288 EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
289 returned_certificate->identity()->certificate().ToPEMString());
290
291 // Shouldn't be able to change the identity once set.
292 EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
293 }
294
295 TEST_F(TransportControllerTest, TestGetRemoteCertificate) {
296 rtc::FakeSSLCertificate fake_certificate("fake_data");
297 rtc::scoped_ptr<rtc::SSLCertificate> returned_certificate;
298
299 FakeTransportChannel* channel = CreateChannel("audio", 1);
300 ASSERT_NE(nullptr, channel);
301
302 channel->SetRemoteCertificate(&fake_certificate);
303 EXPECT_TRUE(transport_controller_->GetRemoteCertificate(
304 "audio", returned_certificate.accept()));
305 EXPECT_EQ(fake_certificate.ToPEMString(),
306 returned_certificate->ToPEMString());
307
308 // Should fail if called for a nonexistant transport.
309 EXPECT_FALSE(transport_controller_->GetRemoteCertificate(
310 "video", returned_certificate.accept()));
311 }
312
313 TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
314 FakeTransportChannel* channel = CreateChannel("audio", 1);
315 ASSERT_NE(nullptr, channel);
316 TransportDescription local_desc(
317 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
318 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
319 std::string err;
320 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
321 "audio", local_desc, cricket::CA_OFFER, &err));
322 // Check that ICE ufrag and pwd were propagated to channel.
323 EXPECT_EQ(kIceUfrag1, channel->ice_ufrag());
324 EXPECT_EQ(kIcePwd1, channel->ice_pwd());
325 // We also expect that the channel started gathering as a result of the
326 // description being set.
327 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
328 EXPECT_EQ(1, gathering_state_signal_count_);
329 }
330
331 TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
332 FakeTransportChannel* channel = CreateChannel("audio", 1);
333 ASSERT_NE(nullptr, channel);
334 TransportDescription remote_desc(
335 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
336 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
337 std::string err;
338 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
339 "audio", remote_desc, cricket::CA_OFFER, &err));
340 // Check that ICE ufrag and pwd were propagated to channel.
341 EXPECT_EQ(kIceUfrag1, channel->remote_ice_ufrag());
342 EXPECT_EQ(kIcePwd1, channel->remote_ice_pwd());
343 }
344
345 TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
346 FakeTransportChannel* channel = CreateChannel("audio", 1);
347 ASSERT_NE(nullptr, channel);
348 Candidates candidates;
349 candidates.push_back(CreateCandidate(1));
350 std::string err;
351 EXPECT_TRUE(
352 transport_controller_->AddRemoteCandidates("audio", candidates, &err));
353 EXPECT_EQ(1U, channel->remote_candidates().size());
354 }
355
356 TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
357 FakeTransportChannel* channel = CreateChannel("audio", 1);
358 ASSERT_NE(nullptr, channel);
359 // We expect to be ready for remote candidates only after local and remote
360 // descriptions are set.
361 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
362
363 std::string err;
364 TransportDescription remote_desc(
365 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
366 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
367 EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
368 "audio", remote_desc, cricket::CA_OFFER, &err));
369 EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));
370
371 TransportDescription local_desc(
372 std::vector<std::string>(), kIceUfrag2, kIcePwd2, cricket::ICEMODE_FULL,
373 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
374 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
375 "audio", local_desc, cricket::CA_ANSWER, &err));
376 EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio"));
377 }
378
379 TEST_F(TransportControllerTest, TestGetStats) {
380 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
381 ASSERT_NE(nullptr, channel1);
382 FakeTransportChannel* channel2 = CreateChannel("audio", 2);
383 ASSERT_NE(nullptr, channel2);
384 FakeTransportChannel* channel3 = CreateChannel("video", 1);
385 ASSERT_NE(nullptr, channel3);
386
387 TransportStats stats;
388 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
389 EXPECT_EQ("audio", stats.transport_name);
390 EXPECT_EQ(2U, stats.channel_stats.size());
391 }
392
393 // Test that transport gets destroyed when it has no more channels.
394 TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
395 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
396 ASSERT_NE(nullptr, channel1);
397 FakeTransportChannel* channel2 = CreateChannel("audio", 1);
398 ASSERT_NE(nullptr, channel2);
399 ASSERT_EQ(channel1, channel2);
400 FakeTransportChannel* channel3 = CreateChannel("audio", 2);
401 ASSERT_NE(nullptr, channel3);
402
403 // Using GetStats to check if transport is destroyed from an outside class's
404 // perspective.
405 TransportStats stats;
406 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
407 DestroyChannel("audio", 2);
408 DestroyChannel("audio", 1);
409 EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
410 DestroyChannel("audio", 1);
411 EXPECT_FALSE(transport_controller_->GetStats("audio", &stats));
412 }
413
414 TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
415 // Need controlling ICE role to get in failed state.
416 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
417 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
418 ASSERT_NE(nullptr, channel1);
419 FakeTransportChannel* channel2 = CreateChannel("video", 1);
420 ASSERT_NE(nullptr, channel2);
421
422 // Should signal "failed" if any channel failed; channel is considered failed
423 // if it previously had a connection but now has none, and gathering is
424 // complete.
425 channel1->SetCandidatesGatheringComplete();
426 channel1->SetConnectionCount(1);
427 channel1->SetConnectionCount(0);
428 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
429 EXPECT_EQ(1, connection_state_signal_count_);
430 }
431
432 TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
433 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
434 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
435 ASSERT_NE(nullptr, channel1);
436 FakeTransportChannel* channel2 = CreateChannel("video", 1);
437 ASSERT_NE(nullptr, channel2);
438 FakeTransportChannel* channel3 = CreateChannel("video", 2);
439 ASSERT_NE(nullptr, channel3);
440
441 // First, have one channel connect, and another fail, to ensure that
442 // the first channel connecting didn't trigger a "connected" state signal.
443 // We should only get a signal when all are connected.
444 channel1->SetConnectionCount(2);
445 channel1->SetWritable(true);
446 channel3->SetCandidatesGatheringComplete();
447 channel3->SetConnectionCount(1);
448 channel3->SetConnectionCount(0);
449 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
450 // Signal count of 1 means that the only signal emitted was "failed".
451 EXPECT_EQ(1, connection_state_signal_count_);
452
453 // Destroy the failed channel to return to "connecting" state.
454 DestroyChannel("video", 2);
455 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
456 kTimeout);
457 EXPECT_EQ(2, connection_state_signal_count_);
458
459 // Make the remaining channel reach a connected state.
460 channel2->SetConnectionCount(2);
461 channel2->SetWritable(true);
462 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
463 EXPECT_EQ(3, connection_state_signal_count_);
464 }
465
466 TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
467 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
468 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
469 ASSERT_NE(nullptr, channel1);
470 FakeTransportChannel* channel2 = CreateChannel("video", 1);
471 ASSERT_NE(nullptr, channel2);
472 FakeTransportChannel* channel3 = CreateChannel("video", 2);
473 ASSERT_NE(nullptr, channel3);
474
475 // Similar to above test, but we're now reaching the completed state, which
476 // means only one connection per FakeTransportChannel.
477 channel1->SetCandidatesGatheringComplete();
478 channel1->SetConnectionCount(1);
479 channel1->SetWritable(true);
480 channel3->SetCandidatesGatheringComplete();
481 channel3->SetConnectionCount(1);
482 channel3->SetConnectionCount(0);
483 EXPECT_EQ_WAIT(cricket::kIceConnectionFailed, connection_state_, kTimeout);
484 // Signal count of 1 means that the only signal emitted was "failed".
485 EXPECT_EQ(1, connection_state_signal_count_);
486
487 // Destroy the failed channel to return to "connecting" state.
488 DestroyChannel("video", 2);
489 EXPECT_EQ_WAIT(cricket::kIceConnectionConnecting, connection_state_,
490 kTimeout);
491 EXPECT_EQ(2, connection_state_signal_count_);
492
493 // Make the remaining channel reach a connected state.
494 channel2->SetCandidatesGatheringComplete();
495 channel2->SetConnectionCount(2);
496 channel2->SetWritable(true);
497 EXPECT_EQ_WAIT(cricket::kIceConnectionConnected, connection_state_, kTimeout);
498 EXPECT_EQ(3, connection_state_signal_count_);
499
500 // Finally, transition to completed state.
501 channel2->SetConnectionCount(1);
502 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
503 EXPECT_EQ(4, connection_state_signal_count_);
504 }
505
506 TEST_F(TransportControllerTest, TestSignalReceiving) {
507 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
508 ASSERT_NE(nullptr, channel1);
509 FakeTransportChannel* channel2 = CreateChannel("video", 1);
510 ASSERT_NE(nullptr, channel2);
511
512 // Should signal receiving as soon as any channel is receiving.
513 channel1->SetReceiving(true);
514 EXPECT_EQ_WAIT(true, receiving_, kTimeout);
515 EXPECT_EQ(1, receiving_signal_count_);
516
517 channel2->SetReceiving(true);
518 channel1->SetReceiving(false);
519 channel2->SetReceiving(false);
520 EXPECT_EQ_WAIT(false, receiving_, kTimeout);
521 EXPECT_EQ(2, receiving_signal_count_);
522 }
523
524 TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
525 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
526 ASSERT_NE(nullptr, channel1);
527 FakeTransportChannel* channel2 = CreateChannel("video", 1);
528 ASSERT_NE(nullptr, channel2);
529 // Connect starts candidate gathering.
530 channel1->Connect();
531 // Should be in the gathering state as soon as any transport starts gathering.
532 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
533 EXPECT_EQ(1, gathering_state_signal_count_);
534 }
535
536 TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
537 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
538 ASSERT_NE(nullptr, channel1);
539 FakeTransportChannel* channel2 = CreateChannel("video", 1);
540 ASSERT_NE(nullptr, channel2);
541 FakeTransportChannel* channel3 = CreateChannel("data", 1);
542 ASSERT_NE(nullptr, channel3);
543
544 channel3->Connect();
545 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
546 EXPECT_EQ(1, gathering_state_signal_count_);
547
548 // Have one channel finish gathering, then destroy it, to make sure gathering
549 // completion wasn't signalled if only one transport finished gathering.
550 channel3->SetCandidatesGatheringComplete();
551 DestroyChannel("data", 1);
552 EXPECT_EQ_WAIT(cricket::kIceGatheringNew, gathering_state_, kTimeout);
553 EXPECT_EQ(2, gathering_state_signal_count_);
554
555 // Make remaining channels start and then finish gathering.
556 channel1->Connect();
557 channel2->Connect();
558 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
559 EXPECT_EQ(3, gathering_state_signal_count_);
560
561 channel1->SetCandidatesGatheringComplete();
562 channel2->SetCandidatesGatheringComplete();
563 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
564 EXPECT_EQ(4, gathering_state_signal_count_);
565 }
566
567 // Test that when the last transport that hasn't finished connecting and/or
568 // gathering is destroyed, the aggregate state jumps to "completed". This can
569 // happen if, for example, we have an audio and video transport, the audio
570 // transport completes, then we start bundling video on the audio transport.
571 TEST_F(TransportControllerTest,
572 TestSignalingWhenLastIncompleteTransportDestroyed) {
573 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
574 FakeTransportChannel* channel1 = CreateChannel("audio", 1);
575 ASSERT_NE(nullptr, channel1);
576 FakeTransportChannel* channel2 = CreateChannel("video", 1);
577 ASSERT_NE(nullptr, channel2);
578
579 channel1->SetCandidatesGatheringComplete();
580 EXPECT_EQ_WAIT(cricket::kIceGatheringGathering, gathering_state_, kTimeout);
581 EXPECT_EQ(1, gathering_state_signal_count_);
582
583 channel1->SetConnectionCount(1);
584 channel1->SetWritable(true);
585 DestroyChannel("video", 1);
586 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
587 EXPECT_EQ(1, connection_state_signal_count_);
588 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
589 EXPECT_EQ(2, gathering_state_signal_count_);
590 }
591
592 TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
593 FakeTransportChannel* channel = CreateChannel("audio", 1);
594 ASSERT_NE(nullptr, channel);
595
596 // Transport won't signal candidates until it has a local description.
597 TransportDescription local_desc(
598 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
599 cricket::CONNECTIONROLE_ACTPASS, nullptr, Candidates());
600 std::string err;
601 EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
602 "audio", local_desc, cricket::CA_OFFER, &err));
603
604 channel->SignalCandidateGathered(channel, CreateCandidate(1));
605 EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout);
606 EXPECT_EQ(1U, candidates_["audio"].size());
607 }
608
609 TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) {
610 CreateTransportControllerWithWorkerThread();
611 CreateChannelsAndCompleteConnectionOnWorkerThread();
612
613 // connecting --> connected --> completed
614 EXPECT_EQ_WAIT(cricket::kIceConnectionCompleted, connection_state_, kTimeout);
615 EXPECT_EQ(2, connection_state_signal_count_);
616
617 EXPECT_EQ_WAIT(true, receiving_, kTimeout);
618 EXPECT_EQ(1, receiving_signal_count_);
619
620 // new --> gathering --> complete
621 EXPECT_EQ_WAIT(cricket::kIceGatheringComplete, gathering_state_, kTimeout);
622 EXPECT_EQ(2, gathering_state_signal_count_);
623
624 EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout);
625 EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout);
626 EXPECT_EQ(2, candidates_signal_count_);
627
628 EXPECT_EQ(false, signaled_on_non_signaling_thread_);
629 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698