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

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

Issue 1350523003: TransportController refactoring. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing Mac test. Created 5 years, 2 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 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 }
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