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

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

Powered by Google App Engine
This is Rietveld 408576698