deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 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> |
jbauch | 555604a | 2016-04-26 03:13:22 -0700 | [diff] [blame] | 12 | #include <memory> |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 13 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 14 | #include "p2p/base/dtlstransport.h" |
| 15 | #include "p2p/base/fakeportallocator.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 16 | #include "p2p/base/p2ptransportchannel.h" |
| 17 | #include "p2p/base/portallocator.h" |
Zhi Huang | b526158 | 2017-09-29 10:51:43 -0700 | [diff] [blame] | 18 | #include "pc/test/faketransportcontroller.h" |
| 19 | #include "pc/transportcontroller.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 20 | #include "rtc_base/fakesslidentity.h" |
| 21 | #include "rtc_base/gunit.h" |
| 22 | #include "rtc_base/helpers.h" |
| 23 | #include "rtc_base/sslidentity.h" |
| 24 | #include "rtc_base/thread.h" |
Zhi Huang | c08de0f | 2017-12-11 00:20:23 -0800 | [diff] [blame] | 25 | #include "test/gtest.h" |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 26 | |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 27 | using webrtc::SdpType; |
| 28 | |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 29 | static const int kTimeout = 100; |
| 30 | static const char kIceUfrag1[] = "TESTICEUFRAG0001"; |
| 31 | static const char kIcePwd1[] = "TESTICEPWD00000000000001"; |
| 32 | static const char kIceUfrag2[] = "TESTICEUFRAG0002"; |
| 33 | static const char kIcePwd2[] = "TESTICEPWD00000000000002"; |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 34 | static const char kIceUfrag3[] = "TESTICEUFRAG0003"; |
| 35 | static const char kIcePwd3[] = "TESTICEPWD00000000000003"; |
Zhi Huang | c08de0f | 2017-12-11 00:20:23 -0800 | [diff] [blame] | 36 | static const bool kRtcpMuxEnabled = true; |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 37 | |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 38 | namespace cricket { |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 39 | |
| 40 | // Only subclassing from FakeTransportController because currently that's the |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 41 | // only way to have a TransportController with fake ICE/DTLS transports. |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 42 | // |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 43 | // TODO(deadbeef): Pass a "TransportFactory" or something similar into |
| 44 | // TransportController, instead of using inheritance in this way for testing. |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 45 | typedef FakeTransportController TransportControllerForTest; |
| 46 | |
| 47 | class TransportControllerTest : public testing::Test, |
| 48 | public sigslot::has_slots<> { |
| 49 | public: |
| 50 | TransportControllerTest() |
| 51 | : transport_controller_(new TransportControllerForTest()), |
| 52 | signaling_thread_(rtc::Thread::Current()) { |
| 53 | ConnectTransportControllerSignals(); |
| 54 | } |
| 55 | |
johan | 27c3d5b | 2016-10-17 00:54:57 -0700 | [diff] [blame] | 56 | void CreateTransportControllerWithNetworkThread() { |
| 57 | if (!network_thread_) { |
| 58 | network_thread_ = rtc::Thread::CreateWithSocketServer(); |
| 59 | network_thread_->Start(); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 60 | } |
| 61 | transport_controller_.reset( |
johan | 27c3d5b | 2016-10-17 00:54:57 -0700 | [diff] [blame] | 62 | new TransportControllerForTest(network_thread_.get())); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 63 | ConnectTransportControllerSignals(); |
| 64 | } |
| 65 | |
| 66 | void ConnectTransportControllerSignals() { |
| 67 | transport_controller_->SignalConnectionState.connect( |
| 68 | this, &TransportControllerTest::OnConnectionState); |
| 69 | transport_controller_->SignalReceiving.connect( |
| 70 | this, &TransportControllerTest::OnReceiving); |
| 71 | transport_controller_->SignalGatheringState.connect( |
| 72 | this, &TransportControllerTest::OnGatheringState); |
| 73 | transport_controller_->SignalCandidatesGathered.connect( |
| 74 | this, &TransportControllerTest::OnCandidatesGathered); |
| 75 | } |
| 76 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 77 | FakeDtlsTransport* CreateFakeDtlsTransport(const std::string& content, |
| 78 | int component) { |
| 79 | DtlsTransportInternal* transport = |
zhihuang | b2cdd93 | 2017-01-19 16:54:25 -0800 | [diff] [blame] | 80 | transport_controller_->CreateDtlsTransport_n(content, component); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 81 | return static_cast<FakeDtlsTransport*>(transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 82 | } |
| 83 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 84 | void DestroyFakeDtlsTransport(const std::string& content, int component) { |
zhihuang | b2cdd93 | 2017-01-19 16:54:25 -0800 | [diff] [blame] | 85 | transport_controller_->DestroyDtlsTransport_n(content, component); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | Candidate CreateCandidate(int component) { |
| 89 | Candidate c; |
| 90 | c.set_address(rtc::SocketAddress("192.168.1.1", 8000)); |
| 91 | c.set_component(1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 92 | c.set_protocol(UDP_PROTOCOL_NAME); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 93 | c.set_priority(1); |
| 94 | return c; |
| 95 | } |
| 96 | |
| 97 | // Used for thread hopping test. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 98 | void CreateFakeDtlsTransportsAndCompleteConnectionOnNetworkThread() { |
johan | 27c3d5b | 2016-10-17 00:54:57 -0700 | [diff] [blame] | 99 | network_thread_->Invoke<void>( |
Taylor Brandstetter | 5d97a9a | 2016-06-10 14:17:27 -0700 | [diff] [blame] | 100 | RTC_FROM_HERE, |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 101 | rtc::Bind(&TransportControllerTest:: |
| 102 | CreateFakeDtlsTransportsAndCompleteConnection_w, |
| 103 | this)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 104 | } |
| 105 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 106 | void CreateFakeDtlsTransportsAndCompleteConnection_w() { |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 107 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 108 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 109 | ASSERT_NE(nullptr, transport1); |
| 110 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 111 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 112 | |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 113 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 114 | kIcePwd1, ICEMODE_FULL, |
| 115 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 116 | std::string err; |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 117 | transport_controller_->SetLocalTransportDescription("audio", local_desc, |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 118 | SdpType::kOffer, &err); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 119 | transport_controller_->SetLocalTransportDescription("video", local_desc, |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 120 | SdpType::kOffer, &err); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 121 | transport_controller_->MaybeStartGathering(); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 122 | transport1->fake_ice_transport()->SignalCandidateGathered( |
| 123 | transport1->fake_ice_transport(), CreateCandidate(1)); |
| 124 | transport2->fake_ice_transport()->SignalCandidateGathered( |
| 125 | transport2->fake_ice_transport(), CreateCandidate(1)); |
| 126 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 127 | transport2->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 128 | transport1->fake_ice_transport()->SetConnectionCount(2); |
| 129 | transport2->fake_ice_transport()->SetConnectionCount(2); |
| 130 | transport1->SetReceiving(true); |
| 131 | transport2->SetReceiving(true); |
| 132 | transport1->SetWritable(true); |
| 133 | transport2->SetWritable(true); |
| 134 | transport1->fake_ice_transport()->SetConnectionCount(1); |
| 135 | transport2->fake_ice_transport()->SetConnectionCount(1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 136 | } |
| 137 | |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 138 | IceConfig CreateIceConfig( |
Honghai Zhang | 5622c5e | 2016-07-01 13:59:29 -0700 | [diff] [blame] | 139 | int receiving_timeout, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 140 | ContinualGatheringPolicy continual_gathering_policy) { |
| 141 | IceConfig config; |
Honghai Zhang | 049fbb1 | 2016-03-07 11:13:07 -0800 | [diff] [blame] | 142 | config.receiving_timeout = receiving_timeout; |
Honghai Zhang | 5622c5e | 2016-07-01 13:59:29 -0700 | [diff] [blame] | 143 | config.continual_gathering_policy = continual_gathering_policy; |
honghaiz | 1f429e3 | 2015-09-28 07:57:34 -0700 | [diff] [blame] | 144 | return config; |
| 145 | } |
| 146 | |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 147 | protected: |
| 148 | void OnConnectionState(IceConnectionState state) { |
| 149 | if (!signaling_thread_->IsCurrent()) { |
| 150 | signaled_on_non_signaling_thread_ = true; |
| 151 | } |
| 152 | connection_state_ = state; |
| 153 | ++connection_state_signal_count_; |
| 154 | } |
| 155 | |
| 156 | void OnReceiving(bool receiving) { |
| 157 | if (!signaling_thread_->IsCurrent()) { |
| 158 | signaled_on_non_signaling_thread_ = true; |
| 159 | } |
| 160 | receiving_ = receiving; |
| 161 | ++receiving_signal_count_; |
| 162 | } |
| 163 | |
| 164 | void OnGatheringState(IceGatheringState state) { |
| 165 | if (!signaling_thread_->IsCurrent()) { |
| 166 | signaled_on_non_signaling_thread_ = true; |
| 167 | } |
| 168 | gathering_state_ = state; |
| 169 | ++gathering_state_signal_count_; |
| 170 | } |
| 171 | |
| 172 | void OnCandidatesGathered(const std::string& transport_name, |
| 173 | const Candidates& candidates) { |
| 174 | if (!signaling_thread_->IsCurrent()) { |
| 175 | signaled_on_non_signaling_thread_ = true; |
| 176 | } |
| 177 | candidates_[transport_name].insert(candidates_[transport_name].end(), |
| 178 | candidates.begin(), candidates.end()); |
| 179 | ++candidates_signal_count_; |
| 180 | } |
| 181 | |
johan | 27c3d5b | 2016-10-17 00:54:57 -0700 | [diff] [blame] | 182 | std::unique_ptr<rtc::Thread> network_thread_; // Not used for most tests. |
jbauch | 555604a | 2016-04-26 03:13:22 -0700 | [diff] [blame] | 183 | std::unique_ptr<TransportControllerForTest> transport_controller_; |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 184 | |
| 185 | // Information received from signals from transport controller. |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 186 | IceConnectionState connection_state_ = kIceConnectionConnecting; |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 187 | bool receiving_ = false; |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 188 | IceGatheringState gathering_state_ = kIceGatheringNew; |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 189 | // transport_name => candidates |
| 190 | std::map<std::string, Candidates> candidates_; |
| 191 | // Counts of each signal emitted. |
| 192 | int connection_state_signal_count_ = 0; |
| 193 | int receiving_signal_count_ = 0; |
| 194 | int gathering_state_signal_count_ = 0; |
| 195 | int candidates_signal_count_ = 0; |
| 196 | |
| 197 | // Used to make sure signals only come on signaling thread. |
| 198 | rtc::Thread* const signaling_thread_ = nullptr; |
| 199 | bool signaled_on_non_signaling_thread_ = false; |
| 200 | }; |
| 201 | |
honghaiz | 1f429e3 | 2015-09-28 07:57:34 -0700 | [diff] [blame] | 202 | TEST_F(TransportControllerTest, TestSetIceConfig) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 203 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 204 | ASSERT_NE(nullptr, transport1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 205 | |
Honghai Zhang | 5622c5e | 2016-07-01 13:59:29 -0700 | [diff] [blame] | 206 | transport_controller_->SetIceConfig( |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 207 | CreateIceConfig(1000, GATHER_CONTINUALLY)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 208 | EXPECT_EQ(1000, transport1->fake_ice_transport()->receiving_timeout()); |
| 209 | EXPECT_TRUE(transport1->fake_ice_transport()->gather_continually()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 210 | |
Honghai Zhang | 5622c5e | 2016-07-01 13:59:29 -0700 | [diff] [blame] | 211 | transport_controller_->SetIceConfig( |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 212 | CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 213 | // Test that value stored in controller is applied to new transports. |
| 214 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 215 | ASSERT_NE(nullptr, transport2); |
| 216 | EXPECT_EQ(1000, transport2->fake_ice_transport()->receiving_timeout()); |
| 217 | EXPECT_TRUE(transport2->fake_ice_transport()->gather_continually()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) { |
| 221 | EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion( |
| 222 | rtc::SSL_PROTOCOL_DTLS_12)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 223 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 224 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 225 | ASSERT_NE(nullptr, transport); |
| 226 | EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, transport->ssl_max_protocol_version()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 227 | |
| 228 | // Setting max version after transport is created should fail. |
| 229 | EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion( |
| 230 | rtc::SSL_PROTOCOL_DTLS_10)); |
| 231 | } |
| 232 | |
| 233 | TEST_F(TransportControllerTest, TestSetIceRole) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 234 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 235 | ASSERT_NE(nullptr, transport1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 236 | |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 237 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 238 | EXPECT_EQ(ICEROLE_CONTROLLING, |
| 239 | transport1->fake_ice_transport()->GetIceRole()); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 240 | transport_controller_->SetIceRole(ICEROLE_CONTROLLED); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 241 | EXPECT_EQ(ICEROLE_CONTROLLED, transport1->fake_ice_transport()->GetIceRole()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 242 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 243 | // Test that value stored in controller is applied to new transports. |
| 244 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 245 | ASSERT_NE(nullptr, transport2); |
| 246 | EXPECT_EQ(ICEROLE_CONTROLLED, transport2->fake_ice_transport()->GetIceRole()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 247 | } |
| 248 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 249 | // Test that when one transport encounters a role conflict, the ICE role is |
| 250 | // swapped on every transport. |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 251 | TEST_F(TransportControllerTest, TestIceRoleConflict) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 252 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 253 | ASSERT_NE(nullptr, transport1); |
| 254 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 255 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 256 | |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 257 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 258 | EXPECT_EQ(ICEROLE_CONTROLLING, |
| 259 | transport1->fake_ice_transport()->GetIceRole()); |
| 260 | EXPECT_EQ(ICEROLE_CONTROLLING, |
| 261 | transport2->fake_ice_transport()->GetIceRole()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 262 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 263 | transport1->fake_ice_transport()->SignalRoleConflict( |
| 264 | transport1->fake_ice_transport()); |
| 265 | EXPECT_EQ(ICEROLE_CONTROLLED, transport1->fake_ice_transport()->GetIceRole()); |
| 266 | EXPECT_EQ(ICEROLE_CONTROLLED, transport2->fake_ice_transport()->GetIceRole()); |
deadbeef | 1c20610 | 2016-05-27 13:34:37 -0700 | [diff] [blame] | 267 | |
| 268 | // Should be able to handle a second role conflict. The remote endpoint can |
| 269 | // change its role/tie-breaker when it does an ICE restart. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 270 | transport2->fake_ice_transport()->SignalRoleConflict( |
| 271 | transport2->fake_ice_transport()); |
| 272 | EXPECT_EQ(ICEROLE_CONTROLLING, |
| 273 | transport1->fake_ice_transport()->GetIceRole()); |
| 274 | EXPECT_EQ(ICEROLE_CONTROLLING, |
| 275 | transport2->fake_ice_transport()->GetIceRole()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 276 | } |
| 277 | |
| 278 | TEST_F(TransportControllerTest, TestGetSslRole) { |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 279 | rtc::SSLRole role; |
deadbeef | d8cfa1a | 2017-03-27 10:33:26 -0700 | [diff] [blame] | 280 | CreateFakeDtlsTransport("audio", 1); |
| 281 | |
| 282 | // Should return false before role has been negotiated. |
| 283 | EXPECT_FALSE(transport_controller_->GetSslRole("audio", &role)); |
| 284 | |
| 285 | // To negotiate an SSL role, need to set a local certificate, and |
| 286 | // local/remote transport descriptions with DTLS info. |
| 287 | rtc::scoped_refptr<rtc::RTCCertificate> certificate = |
| 288 | rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( |
| 289 | rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA))); |
| 290 | std::unique_ptr<rtc::SSLFingerprint> fingerprint( |
| 291 | rtc::SSLFingerprint::CreateFromCertificate(certificate)); |
| 292 | transport_controller_->SetLocalCertificate(certificate); |
| 293 | |
| 294 | // Set the same fingerprint on both sides since the remote fingerprint |
| 295 | // doesn't really matter for this test. |
| 296 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1, |
| 297 | kIcePwd1, ICEMODE_FULL, |
| 298 | CONNECTIONROLE_ACTPASS, fingerprint.get()); |
| 299 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag2, |
| 300 | kIcePwd2, ICEMODE_FULL, |
| 301 | CONNECTIONROLE_ACTIVE, fingerprint.get()); |
| 302 | std::string err; |
| 303 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 304 | "audio", local_desc, SdpType::kOffer, &err)); |
deadbeef | d8cfa1a | 2017-03-27 10:33:26 -0700 | [diff] [blame] | 305 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 306 | "audio", remote_desc, SdpType::kAnswer, &err)); |
deadbeef | d8cfa1a | 2017-03-27 10:33:26 -0700 | [diff] [blame] | 307 | |
| 308 | // Finally we can get the role. Should be "server" since the remote |
| 309 | // endpoint's role was "active". |
Taylor Brandstetter | f475d36 | 2016-01-08 15:35:57 -0800 | [diff] [blame] | 310 | EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role)); |
deadbeef | d8cfa1a | 2017-03-27 10:33:26 -0700 | [diff] [blame] | 311 | EXPECT_EQ(rtc::SSL_SERVER, role); |
| 312 | |
| 313 | // Lastly, test that GetSslRole returns false for a nonexistent transport. |
| 314 | EXPECT_FALSE(transport_controller_->GetSslRole("video", &role)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 315 | } |
| 316 | |
| 317 | TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) { |
| 318 | rtc::scoped_refptr<rtc::RTCCertificate> certificate1 = |
jbauch | 555604a | 2016-04-26 03:13:22 -0700 | [diff] [blame] | 319 | rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( |
kwiberg | 0eb15ed | 2015-12-17 03:04:15 -0800 | [diff] [blame] | 320 | rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT))); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 321 | rtc::scoped_refptr<rtc::RTCCertificate> certificate2 = |
jbauch | 555604a | 2016-04-26 03:13:22 -0700 | [diff] [blame] | 322 | rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( |
kwiberg | 0eb15ed | 2015-12-17 03:04:15 -0800 | [diff] [blame] | 323 | rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT))); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 324 | rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate; |
| 325 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 326 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 327 | ASSERT_NE(nullptr, transport1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 328 | |
| 329 | EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1)); |
| 330 | EXPECT_TRUE(transport_controller_->GetLocalCertificate( |
| 331 | "audio", &returned_certificate)); |
| 332 | EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), |
| 333 | returned_certificate->identity()->certificate().ToPEMString()); |
| 334 | |
| 335 | // Should fail if called for a nonexistant transport. |
| 336 | EXPECT_FALSE(transport_controller_->GetLocalCertificate( |
| 337 | "video", &returned_certificate)); |
| 338 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 339 | // Test that identity stored in controller is applied to new transports. |
| 340 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 341 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 342 | EXPECT_TRUE(transport_controller_->GetLocalCertificate( |
| 343 | "video", &returned_certificate)); |
| 344 | EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(), |
| 345 | returned_certificate->identity()->certificate().ToPEMString()); |
| 346 | |
| 347 | // Shouldn't be able to change the identity once set. |
| 348 | EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2)); |
| 349 | } |
| 350 | |
| 351 | TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) { |
| 352 | rtc::FakeSSLCertificate fake_certificate("fake_data"); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 353 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 354 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 355 | ASSERT_NE(nullptr, transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 356 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 357 | transport->SetRemoteSSLCertificate(&fake_certificate); |
jbauch | 555604a | 2016-04-26 03:13:22 -0700 | [diff] [blame] | 358 | std::unique_ptr<rtc::SSLCertificate> returned_certificate = |
kwiberg | b4d01c4 | 2016-04-06 05:15:06 -0700 | [diff] [blame] | 359 | transport_controller_->GetRemoteSSLCertificate("audio"); |
| 360 | EXPECT_TRUE(returned_certificate); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 361 | EXPECT_EQ(fake_certificate.ToPEMString(), |
| 362 | returned_certificate->ToPEMString()); |
| 363 | |
| 364 | // Should fail if called for a nonexistant transport. |
kwiberg | b4d01c4 | 2016-04-06 05:15:06 -0700 | [diff] [blame] | 365 | EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate("video")); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 366 | } |
| 367 | |
| 368 | TEST_F(TransportControllerTest, TestSetLocalTransportDescription) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 369 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 370 | ASSERT_NE(nullptr, transport); |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 371 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 372 | kIcePwd1, ICEMODE_FULL, |
| 373 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 374 | std::string err; |
| 375 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 376 | "audio", local_desc, SdpType::kOffer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 377 | // Check that ICE ufrag and pwd were propagated to transport. |
| 378 | EXPECT_EQ(kIceUfrag1, transport->fake_ice_transport()->ice_ufrag()); |
| 379 | EXPECT_EQ(kIcePwd1, transport->fake_ice_transport()->ice_pwd()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 380 | // After setting local description, we should be able to start gathering |
| 381 | // candidates. |
| 382 | transport_controller_->MaybeStartGathering(); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 383 | EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 384 | EXPECT_EQ(1, gathering_state_signal_count_); |
| 385 | } |
| 386 | |
| 387 | TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 388 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 389 | ASSERT_NE(nullptr, transport); |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 390 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 391 | kIcePwd1, ICEMODE_FULL, |
| 392 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 393 | std::string err; |
| 394 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 395 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 396 | // Check that ICE ufrag and pwd were propagated to transport. |
| 397 | EXPECT_EQ(kIceUfrag1, transport->fake_ice_transport()->remote_ice_ufrag()); |
| 398 | EXPECT_EQ(kIcePwd1, transport->fake_ice_transport()->remote_ice_pwd()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 399 | } |
| 400 | |
| 401 | TEST_F(TransportControllerTest, TestAddRemoteCandidates) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 402 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 403 | ASSERT_NE(nullptr, transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 404 | Candidates candidates; |
| 405 | candidates.push_back(CreateCandidate(1)); |
| 406 | std::string err; |
| 407 | EXPECT_TRUE( |
| 408 | transport_controller_->AddRemoteCandidates("audio", candidates, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 409 | EXPECT_EQ(1U, transport->fake_ice_transport()->remote_candidates().size()); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 410 | } |
| 411 | |
| 412 | TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 413 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 414 | ASSERT_NE(nullptr, transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 415 | // We expect to be ready for remote candidates only after local and remote |
| 416 | // descriptions are set. |
| 417 | EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); |
| 418 | |
| 419 | std::string err; |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 420 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 421 | kIcePwd1, ICEMODE_FULL, |
| 422 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 423 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 424 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 425 | EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio")); |
| 426 | |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 427 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 428 | kIcePwd2, ICEMODE_FULL, |
| 429 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 430 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 431 | "audio", local_desc, SdpType::kAnswer, &err)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 432 | EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio")); |
| 433 | } |
| 434 | |
| 435 | TEST_F(TransportControllerTest, TestGetStats) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 436 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 437 | ASSERT_NE(nullptr, transport1); |
| 438 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("audio", 2); |
| 439 | ASSERT_NE(nullptr, transport2); |
| 440 | FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 1); |
| 441 | ASSERT_NE(nullptr, transport3); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 442 | |
| 443 | TransportStats stats; |
| 444 | EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); |
| 445 | EXPECT_EQ("audio", stats.transport_name); |
| 446 | EXPECT_EQ(2U, stats.channel_stats.size()); |
| 447 | } |
| 448 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 449 | // Test that a "transport" from a stats perspective (combination of RTP/RTCP |
| 450 | // transports) goes away when all references to its transports are gone. |
| 451 | TEST_F(TransportControllerTest, TestCreateAndDestroyFakeDtlsTransport) { |
| 452 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 453 | ASSERT_NE(nullptr, transport1); |
| 454 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("audio", 1); |
| 455 | ASSERT_NE(nullptr, transport2); |
| 456 | ASSERT_EQ(transport1, transport2); |
| 457 | FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("audio", 2); |
| 458 | ASSERT_NE(nullptr, transport3); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 459 | |
| 460 | // Using GetStats to check if transport is destroyed from an outside class's |
| 461 | // perspective. |
| 462 | TransportStats stats; |
| 463 | EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 464 | DestroyFakeDtlsTransport("audio", 2); |
| 465 | DestroyFakeDtlsTransport("audio", 1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 466 | EXPECT_TRUE(transport_controller_->GetStats("audio", &stats)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 467 | DestroyFakeDtlsTransport("audio", 1); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 468 | EXPECT_FALSE(transport_controller_->GetStats("audio", &stats)); |
| 469 | } |
| 470 | |
| 471 | TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) { |
| 472 | // Need controlling ICE role to get in failed state. |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 473 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 474 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 475 | ASSERT_NE(nullptr, transport1); |
| 476 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 477 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 478 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 479 | // Should signal "failed" if any transport failed; transport is considered |
| 480 | // failed |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 481 | // if it previously had a connection but now has none, and gathering is |
| 482 | // complete. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 483 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 484 | transport1->fake_ice_transport()->SetConnectionCount(1); |
| 485 | transport1->fake_ice_transport()->SetConnectionCount(0); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 486 | EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 487 | EXPECT_EQ(1, connection_state_signal_count_); |
| 488 | } |
| 489 | |
| 490 | TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) { |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 491 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 492 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 493 | ASSERT_NE(nullptr, transport1); |
| 494 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 495 | ASSERT_NE(nullptr, transport2); |
| 496 | FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 2); |
| 497 | ASSERT_NE(nullptr, transport3); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 498 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 499 | // First, have one transport connect, and another fail, to ensure that |
| 500 | // the first transport connecting didn't trigger a "connected" state signal. |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 501 | // We should only get a signal when all are connected. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 502 | transport1->fake_ice_transport()->SetConnectionCount(2); |
| 503 | transport1->SetWritable(true); |
| 504 | transport3->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 505 | transport3->fake_ice_transport()->SetConnectionCount(1); |
| 506 | transport3->fake_ice_transport()->SetConnectionCount(0); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 507 | EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 508 | // Signal count of 1 means that the only signal emitted was "failed". |
| 509 | EXPECT_EQ(1, connection_state_signal_count_); |
| 510 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 511 | // Destroy the failed transport to return to "connecting" state. |
| 512 | DestroyFakeDtlsTransport("video", 2); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 513 | EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 514 | EXPECT_EQ(2, connection_state_signal_count_); |
| 515 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 516 | // Make the remaining transport reach a connected state. |
| 517 | transport2->fake_ice_transport()->SetConnectionCount(2); |
| 518 | transport2->SetWritable(true); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 519 | EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 520 | EXPECT_EQ(3, connection_state_signal_count_); |
| 521 | } |
| 522 | |
| 523 | TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) { |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 524 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 525 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 526 | ASSERT_NE(nullptr, transport1); |
| 527 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 528 | ASSERT_NE(nullptr, transport2); |
| 529 | FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 2); |
| 530 | ASSERT_NE(nullptr, transport3); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 531 | |
| 532 | // Similar to above test, but we're now reaching the completed state, which |
zhihuang | b2cdd93 | 2017-01-19 16:54:25 -0800 | [diff] [blame] | 533 | // means only one connection per FakeDtlsTransport. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 534 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 535 | transport1->fake_ice_transport()->SetConnectionCount(1); |
| 536 | transport1->SetWritable(true); |
| 537 | transport3->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 538 | transport3->fake_ice_transport()->SetConnectionCount(1); |
| 539 | transport3->fake_ice_transport()->SetConnectionCount(0); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 540 | EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 541 | // Signal count of 1 means that the only signal emitted was "failed". |
| 542 | EXPECT_EQ(1, connection_state_signal_count_); |
| 543 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 544 | // Destroy the failed transport to return to "connecting" state. |
| 545 | DestroyFakeDtlsTransport("video", 2); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 546 | EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 547 | EXPECT_EQ(2, connection_state_signal_count_); |
| 548 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 549 | // Make the remaining transport reach a connected state. |
| 550 | transport2->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 551 | transport2->fake_ice_transport()->SetConnectionCount(2); |
| 552 | transport2->SetWritable(true); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 553 | EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 554 | EXPECT_EQ(3, connection_state_signal_count_); |
| 555 | |
| 556 | // Finally, transition to completed state. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 557 | transport2->fake_ice_transport()->SetConnectionCount(1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 558 | EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 559 | EXPECT_EQ(4, connection_state_signal_count_); |
| 560 | } |
| 561 | |
| 562 | // Make sure that if we're "connected" and remove a transport, we stay in the |
| 563 | // "connected" state. |
| 564 | TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 565 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 566 | ASSERT_NE(nullptr, transport1); |
| 567 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 568 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 569 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 570 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 571 | transport1->fake_ice_transport()->SetConnectionCount(2); |
| 572 | transport1->SetWritable(true); |
| 573 | transport2->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 574 | transport2->fake_ice_transport()->SetConnectionCount(2); |
| 575 | transport2->SetWritable(true); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 576 | EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 577 | EXPECT_EQ(1, connection_state_signal_count_); |
| 578 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 579 | // Destroy one transport, then "complete" the other one, so we reach |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 580 | // a known state. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 581 | DestroyFakeDtlsTransport("video", 1); |
| 582 | transport1->fake_ice_transport()->SetConnectionCount(1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 583 | EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 584 | // Signal count of 2 means the deletion didn't cause any unexpected signals |
| 585 | EXPECT_EQ(2, connection_state_signal_count_); |
| 586 | } |
| 587 | |
| 588 | // If we destroy the last/only transport, we should simply transition to |
| 589 | // "connecting". |
| 590 | TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 591 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 592 | ASSERT_NE(nullptr, transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 593 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 594 | transport->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 595 | transport->fake_ice_transport()->SetConnectionCount(2); |
| 596 | transport->SetWritable(true); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 597 | EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 598 | EXPECT_EQ(1, connection_state_signal_count_); |
| 599 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 600 | DestroyFakeDtlsTransport("audio", 1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 601 | EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 602 | // Signal count of 2 means the deletion didn't cause any unexpected signals |
| 603 | EXPECT_EQ(2, connection_state_signal_count_); |
| 604 | } |
| 605 | |
| 606 | TEST_F(TransportControllerTest, TestSignalReceiving) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 607 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 608 | ASSERT_NE(nullptr, transport1); |
| 609 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 610 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 611 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 612 | // Should signal receiving as soon as any transport is receiving. |
| 613 | transport1->SetReceiving(true); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 614 | EXPECT_TRUE_WAIT(receiving_, kTimeout); |
| 615 | EXPECT_EQ(1, receiving_signal_count_); |
| 616 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 617 | transport2->SetReceiving(true); |
| 618 | transport1->SetReceiving(false); |
| 619 | transport2->SetReceiving(false); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 620 | EXPECT_TRUE_WAIT(!receiving_, kTimeout); |
| 621 | EXPECT_EQ(2, receiving_signal_count_); |
| 622 | } |
| 623 | |
| 624 | TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 625 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 626 | ASSERT_NE(nullptr, transport); |
| 627 | transport->fake_ice_transport()->MaybeStartGathering(); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 628 | // Should be in the gathering state as soon as any transport starts gathering. |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 629 | EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 630 | EXPECT_EQ(1, gathering_state_signal_count_); |
| 631 | } |
| 632 | |
| 633 | TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 634 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 635 | ASSERT_NE(nullptr, transport1); |
| 636 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 637 | ASSERT_NE(nullptr, transport2); |
| 638 | FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("data", 1); |
| 639 | ASSERT_NE(nullptr, transport3); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 640 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 641 | transport3->fake_ice_transport()->MaybeStartGathering(); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 642 | EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 643 | EXPECT_EQ(1, gathering_state_signal_count_); |
| 644 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 645 | // Have one transport finish gathering, then destroy it, to make sure |
| 646 | // gathering |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 647 | // completion wasn't signalled if only one transport finished gathering. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 648 | transport3->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 649 | DestroyFakeDtlsTransport("data", 1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 650 | EXPECT_EQ_WAIT(kIceGatheringNew, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 651 | EXPECT_EQ(2, gathering_state_signal_count_); |
| 652 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 653 | // Make remaining transports start and then finish gathering. |
| 654 | transport1->fake_ice_transport()->MaybeStartGathering(); |
| 655 | transport2->fake_ice_transport()->MaybeStartGathering(); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 656 | EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 657 | EXPECT_EQ(3, gathering_state_signal_count_); |
| 658 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 659 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
| 660 | transport2->fake_ice_transport()->SetCandidatesGatheringComplete(); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 661 | EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 662 | EXPECT_EQ(4, gathering_state_signal_count_); |
| 663 | } |
| 664 | |
| 665 | // Test that when the last transport that hasn't finished connecting and/or |
| 666 | // gathering is destroyed, the aggregate state jumps to "completed". This can |
| 667 | // happen if, for example, we have an audio and video transport, the audio |
| 668 | // transport completes, then we start bundling video on the audio transport. |
| 669 | TEST_F(TransportControllerTest, |
| 670 | TestSignalingWhenLastIncompleteTransportDestroyed) { |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 671 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 672 | FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1); |
| 673 | ASSERT_NE(nullptr, transport1); |
| 674 | FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1); |
| 675 | ASSERT_NE(nullptr, transport2); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 676 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 677 | transport1->fake_ice_transport()->SetCandidatesGatheringComplete(); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 678 | EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 679 | EXPECT_EQ(1, gathering_state_signal_count_); |
| 680 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 681 | transport1->fake_ice_transport()->SetConnectionCount(1); |
| 682 | transport1->SetWritable(true); |
| 683 | DestroyFakeDtlsTransport("video", 1); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 684 | EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 685 | EXPECT_EQ(1, connection_state_signal_count_); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 686 | EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 687 | EXPECT_EQ(2, gathering_state_signal_count_); |
| 688 | } |
| 689 | |
| 690 | TEST_F(TransportControllerTest, TestSignalCandidatesGathered) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 691 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 692 | ASSERT_NE(nullptr, transport); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 693 | |
| 694 | // Transport won't signal candidates until it has a local description. |
deadbeef | 46eed76 | 2016-01-28 13:24:37 -0800 | [diff] [blame] | 695 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1, |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 696 | kIcePwd1, ICEMODE_FULL, |
| 697 | CONNECTIONROLE_ACTPASS, nullptr); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 698 | std::string err; |
| 699 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 700 | "audio", local_desc, SdpType::kOffer, &err)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 701 | transport_controller_->MaybeStartGathering(); |
| 702 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 703 | transport->fake_ice_transport()->SignalCandidateGathered( |
| 704 | transport->fake_ice_transport(), CreateCandidate(1)); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 705 | EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout); |
| 706 | EXPECT_EQ(1U, candidates_["audio"].size()); |
| 707 | } |
| 708 | |
| 709 | TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) { |
johan | 27c3d5b | 2016-10-17 00:54:57 -0700 | [diff] [blame] | 710 | CreateTransportControllerWithNetworkThread(); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 711 | CreateFakeDtlsTransportsAndCompleteConnectionOnNetworkThread(); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 712 | |
| 713 | // connecting --> connected --> completed |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 714 | EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 715 | EXPECT_EQ(2, connection_state_signal_count_); |
| 716 | |
| 717 | EXPECT_TRUE_WAIT(receiving_, kTimeout); |
| 718 | EXPECT_EQ(1, receiving_signal_count_); |
| 719 | |
| 720 | // new --> gathering --> complete |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 721 | EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout); |
deadbeef | cbecd35 | 2015-09-23 11:50:27 -0700 | [diff] [blame] | 722 | EXPECT_EQ(2, gathering_state_signal_count_); |
| 723 | |
| 724 | EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout); |
| 725 | EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout); |
| 726 | EXPECT_EQ(2, candidates_signal_count_); |
| 727 | |
| 728 | EXPECT_TRUE(!signaled_on_non_signaling_thread_); |
| 729 | } |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 730 | |
| 731 | // Older versions of Chrome expect the ICE role to be re-determined when an |
| 732 | // ICE restart occurs, and also don't perform conflict resolution correctly, |
| 733 | // so for now we can't safely stop doing this. |
| 734 | // See: https://bugs.chromium.org/p/chromium/issues/detail?id=628676 |
| 735 | // TODO(deadbeef): Remove this when these old versions of Chrome reach a low |
| 736 | // enough population. |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 737 | TEST_F(TransportControllerTest, IceRoleRedeterminedOnIceRestartByDefault) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 738 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 739 | ASSERT_NE(nullptr, transport); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 740 | std::string err; |
| 741 | // Do an initial offer answer, so that the next offer is an ICE restart. |
| 742 | transport_controller_->SetIceRole(ICEROLE_CONTROLLED); |
| 743 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
| 744 | kIcePwd1, ICEMODE_FULL, |
| 745 | CONNECTIONROLE_ACTPASS, nullptr); |
| 746 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 747 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 748 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2, |
| 749 | kIcePwd2, ICEMODE_FULL, |
| 750 | CONNECTIONROLE_ACTPASS, nullptr); |
| 751 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 752 | "audio", local_desc, SdpType::kAnswer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 753 | EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole()); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 754 | |
| 755 | // The endpoint that initiated an ICE restart should take the controlling |
| 756 | // role. |
| 757 | TransportDescription ice_restart_desc(std::vector<std::string>(), kIceUfrag3, |
| 758 | kIcePwd3, ICEMODE_FULL, |
| 759 | CONNECTIONROLE_ACTPASS, nullptr); |
| 760 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 761 | "audio", ice_restart_desc, SdpType::kOffer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 762 | EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole()); |
deadbeef | 91042f8 | 2016-07-15 17:48:13 -0700 | [diff] [blame] | 763 | } |
| 764 | |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 765 | // Test that if the TransportController was created with the |
| 766 | // |redetermine_role_on_ice_restart| parameter set to false, the role is *not* |
| 767 | // redetermined on an ICE restart. |
| 768 | TEST_F(TransportControllerTest, IceRoleNotRedetermined) { |
| 769 | bool redetermine_role = false; |
| 770 | transport_controller_.reset(new TransportControllerForTest(redetermine_role)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 771 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 772 | ASSERT_NE(nullptr, transport); |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 773 | std::string err; |
| 774 | // Do an initial offer answer, so that the next offer is an ICE restart. |
| 775 | transport_controller_->SetIceRole(ICEROLE_CONTROLLED); |
| 776 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
| 777 | kIcePwd1, ICEMODE_FULL, |
| 778 | CONNECTIONROLE_ACTPASS, nullptr); |
| 779 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 780 | "audio", remote_desc, SdpType::kOffer, &err)); |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 781 | TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2, |
| 782 | kIcePwd2, ICEMODE_FULL, |
| 783 | CONNECTIONROLE_ACTPASS, nullptr); |
| 784 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 785 | "audio", local_desc, SdpType::kAnswer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 786 | EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole()); |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 787 | |
| 788 | // The endpoint that initiated an ICE restart should keep the existing role. |
| 789 | TransportDescription ice_restart_desc(std::vector<std::string>(), kIceUfrag3, |
| 790 | kIcePwd3, ICEMODE_FULL, |
| 791 | CONNECTIONROLE_ACTPASS, nullptr); |
| 792 | EXPECT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 793 | "audio", ice_restart_desc, SdpType::kOffer, &err)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 794 | EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole()); |
Taylor Brandstetter | f0bb360 | 2016-08-26 20:59:24 -0700 | [diff] [blame] | 795 | } |
| 796 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 797 | // Tests ICE role is reversed after receiving ice-lite from remote. |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 798 | TEST_F(TransportControllerTest, TestSetRemoteIceLiteInOffer) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 799 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 800 | ASSERT_NE(nullptr, transport); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 801 | std::string err; |
| 802 | |
| 803 | transport_controller_->SetIceRole(ICEROLE_CONTROLLED); |
| 804 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
| 805 | kIcePwd1, ICEMODE_LITE, |
| 806 | CONNECTIONROLE_ACTPASS, nullptr); |
| 807 | EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 808 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 809 | TransportDescription local_desc(kIceUfrag1, kIcePwd1); |
| 810 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 811 | "audio", local_desc, SdpType::kAnswer, nullptr)); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 812 | |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 813 | EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole()); |
| 814 | EXPECT_EQ(ICEMODE_LITE, transport->fake_ice_transport()->remote_ice_mode()); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 815 | } |
| 816 | |
| 817 | // Tests ice-lite in remote answer. |
| 818 | TEST_F(TransportControllerTest, TestSetRemoteIceLiteInAnswer) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 819 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 820 | ASSERT_NE(nullptr, transport); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 821 | std::string err; |
| 822 | |
| 823 | transport_controller_->SetIceRole(ICEROLE_CONTROLLING); |
| 824 | TransportDescription local_desc(kIceUfrag1, kIcePwd1); |
| 825 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 826 | "audio", local_desc, SdpType::kOffer, nullptr)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 827 | EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole()); |
| 828 | // Transports will be created in ICEFULL_MODE. |
| 829 | EXPECT_EQ(ICEMODE_FULL, transport->fake_ice_transport()->remote_ice_mode()); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 830 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
| 831 | kIcePwd1, ICEMODE_LITE, CONNECTIONROLE_NONE, |
| 832 | nullptr); |
| 833 | ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 834 | "audio", remote_desc, SdpType::kAnswer, nullptr)); |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 835 | EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole()); |
| 836 | // After receiving remote description with ICEMODE_LITE, transport should |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 837 | // have mode set to ICEMODE_LITE. |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 838 | EXPECT_EQ(ICEMODE_LITE, transport->fake_ice_transport()->remote_ice_mode()); |
deadbeef | 49f34fd | 2016-12-06 16:22:06 -0800 | [diff] [blame] | 839 | } |
| 840 | |
deadbeef | 897d08e | 2017-04-20 00:57:25 -0700 | [diff] [blame] | 841 | // Tests that the ICE role remains "controlling" if a subsequent offer that |
| 842 | // does an ICE restart is received from an ICE lite endpoint. Regression test |
| 843 | // for: https://crbug.com/710760 |
| 844 | TEST_F(TransportControllerTest, |
| 845 | IceRoleIsControllingAfterIceRestartFromIceLiteEndpoint) { |
| 846 | FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1); |
| 847 | ASSERT_NE(nullptr, transport); |
| 848 | std::string err; |
| 849 | |
| 850 | // Initial offer/answer. |
| 851 | TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1, |
| 852 | kIcePwd1, ICEMODE_LITE, |
| 853 | CONNECTIONROLE_ACTPASS, nullptr); |
| 854 | TransportDescription local_desc(kIceUfrag1, kIcePwd1); |
| 855 | ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 856 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | 897d08e | 2017-04-20 00:57:25 -0700 | [diff] [blame] | 857 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 858 | "audio", local_desc, SdpType::kAnswer, nullptr)); |
deadbeef | 897d08e | 2017-04-20 00:57:25 -0700 | [diff] [blame] | 859 | // Subsequent ICE restart offer/answer. |
| 860 | remote_desc.ice_ufrag = kIceUfrag2; |
| 861 | remote_desc.ice_pwd = kIcePwd2; |
| 862 | local_desc.ice_ufrag = kIceUfrag2; |
| 863 | local_desc.ice_pwd = kIcePwd2; |
| 864 | ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 865 | "audio", remote_desc, SdpType::kOffer, &err)); |
deadbeef | 897d08e | 2017-04-20 00:57:25 -0700 | [diff] [blame] | 866 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 867 | "audio", local_desc, SdpType::kAnswer, nullptr)); |
deadbeef | 897d08e | 2017-04-20 00:57:25 -0700 | [diff] [blame] | 868 | |
| 869 | EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole()); |
| 870 | } |
| 871 | |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 872 | // Tests SetNeedsIceRestartFlag and NeedsIceRestart, setting the flag and then |
| 873 | // initiating an ICE restart for one of the transports. |
| 874 | TEST_F(TransportControllerTest, NeedsIceRestart) { |
deadbeef | f534659 | 2017-01-24 21:51:21 -0800 | [diff] [blame] | 875 | CreateFakeDtlsTransport("audio", 1); |
| 876 | CreateFakeDtlsTransport("video", 1); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 877 | |
| 878 | // Do initial offer/answer so there's something to restart. |
| 879 | TransportDescription local_desc(kIceUfrag1, kIcePwd1); |
| 880 | TransportDescription remote_desc(kIceUfrag1, kIcePwd1); |
| 881 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 882 | "audio", local_desc, SdpType::kOffer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 883 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 884 | "video", local_desc, SdpType::kOffer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 885 | ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 886 | "audio", remote_desc, SdpType::kAnswer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 887 | ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 888 | "video", remote_desc, SdpType::kAnswer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 889 | |
| 890 | // Initially NeedsIceRestart should return false. |
| 891 | EXPECT_FALSE(transport_controller_->NeedsIceRestart("audio")); |
| 892 | EXPECT_FALSE(transport_controller_->NeedsIceRestart("video")); |
| 893 | |
| 894 | // Set the needs-ice-restart flag and verify NeedsIceRestart starts returning |
| 895 | // true. |
| 896 | transport_controller_->SetNeedsIceRestartFlag(); |
| 897 | EXPECT_TRUE(transport_controller_->NeedsIceRestart("audio")); |
| 898 | EXPECT_TRUE(transport_controller_->NeedsIceRestart("video")); |
| 899 | // For a nonexistent transport, false should be returned. |
| 900 | EXPECT_FALSE(transport_controller_->NeedsIceRestart("deadbeef")); |
| 901 | |
| 902 | // Do ICE restart but only for audio. |
| 903 | TransportDescription ice_restart_local_desc(kIceUfrag2, kIcePwd2); |
| 904 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 905 | "audio", ice_restart_local_desc, SdpType::kOffer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 906 | ASSERT_TRUE(transport_controller_->SetLocalTransportDescription( |
Steve Anton | 3828c06 | 2017-12-06 10:34:51 -0800 | [diff] [blame] | 907 | "video", local_desc, SdpType::kOffer, nullptr)); |
deadbeef | d1a38b5 | 2016-12-10 13:15:33 -0800 | [diff] [blame] | 908 | // NeedsIceRestart should still be true for video. |
| 909 | EXPECT_FALSE(transport_controller_->NeedsIceRestart("audio")); |
| 910 | EXPECT_TRUE(transport_controller_->NeedsIceRestart("video")); |
| 911 | } |
| 912 | |
Zhi Huang | c08de0f | 2017-12-11 00:20:23 -0800 | [diff] [blame] | 913 | enum class RTPTransportType { kSdes, kDtlsSrtp }; |
| 914 | std::ostream& operator<<(std::ostream& out, RTPTransportType value) { |
| 915 | switch (value) { |
| 916 | case RTPTransportType::kSdes: |
| 917 | return out << "SDES"; |
| 918 | case RTPTransportType::kDtlsSrtp: |
| 919 | return out << "DTLS-SRTP"; |
| 920 | } |
| 921 | return out; |
| 922 | } |
| 923 | |
| 924 | // Tests the TransportController can correctly create and destroy the RTP |
| 925 | // transports. |
| 926 | class TransportControllerRTPTransportTest |
| 927 | : public TransportControllerTest, |
| 928 | public ::testing::WithParamInterface<RTPTransportType> { |
| 929 | protected: |
| 930 | // Helper function used to create an RTP layer transport. |
| 931 | webrtc::RtpTransportInternal* CreateRtpTransport( |
| 932 | const std::string& transport_name) { |
| 933 | RTPTransportType type = GetParam(); |
| 934 | switch (type) { |
| 935 | case RTPTransportType::kSdes: |
| 936 | return transport_controller_->CreateSdesTransport(transport_name, |
| 937 | kRtcpMuxEnabled); |
| 938 | case RTPTransportType::kDtlsSrtp: |
| 939 | return transport_controller_->CreateDtlsSrtpTransport(transport_name, |
| 940 | kRtcpMuxEnabled); |
| 941 | } |
| 942 | return nullptr; |
| 943 | } |
| 944 | }; |
| 945 | |
| 946 | // Tests that creating transports with the same name will cause the |
| 947 | // second call to re-use the transport created in the first call. |
| 948 | TEST_P(TransportControllerRTPTransportTest, CreateTransportsWithReference) { |
| 949 | const std::string transport_name = "transport"; |
| 950 | webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name); |
| 951 | webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name); |
| 952 | EXPECT_NE(nullptr, transport1); |
| 953 | EXPECT_NE(nullptr, transport2); |
| 954 | // The TransportController is expected to return the existing one when using |
| 955 | // the same transport name. |
| 956 | EXPECT_EQ(transport1, transport2); |
| 957 | transport_controller_->DestroyTransport(transport_name); |
| 958 | transport_controller_->DestroyTransport(transport_name); |
| 959 | } |
| 960 | |
| 961 | // Tests that creating different type of RTP transports with same name is not |
| 962 | // allowed. |
| 963 | TEST_P(TransportControllerRTPTransportTest, |
| 964 | CreateDifferentTypeOfTransportsWithSameName) { |
| 965 | const std::string transport_name = "transport"; |
| 966 | webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name); |
| 967 | EXPECT_NE(nullptr, transport1); |
| 968 | RTPTransportType type = GetParam(); |
| 969 | switch (type) { |
| 970 | case RTPTransportType::kSdes: |
| 971 | EXPECT_EQ(nullptr, transport_controller_->CreateDtlsSrtpTransport( |
| 972 | transport_name, kRtcpMuxEnabled)); |
| 973 | break; |
| 974 | case RTPTransportType::kDtlsSrtp: |
| 975 | EXPECT_EQ(nullptr, transport_controller_->CreateSdesTransport( |
| 976 | transport_name, kRtcpMuxEnabled)); |
| 977 | break; |
| 978 | default: |
| 979 | ASSERT_TRUE(false); |
| 980 | } |
| 981 | transport_controller_->DestroyTransport(transport_name); |
| 982 | } |
| 983 | |
| 984 | // Tests the RTP transport is not actually destroyed if references still exist. |
| 985 | TEST_P(TransportControllerRTPTransportTest, DestroyTransportWithReference) { |
| 986 | const std::string transport_name = "transport"; |
| 987 | webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name); |
| 988 | webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name); |
| 989 | EXPECT_NE(nullptr, transport1); |
| 990 | EXPECT_NE(nullptr, transport2); |
| 991 | transport_controller_->DestroyTransport(transport_name); |
| 992 | EXPECT_NE(nullptr, transport1->rtp_packet_transport()); |
| 993 | EXPECT_EQ(nullptr, transport1->rtcp_packet_transport()); |
| 994 | transport_controller_->DestroyTransport(transport_name); |
| 995 | } |
| 996 | |
| 997 | // Tests the RTP is actually destroyed if there is no reference to it. |
Harald Alvestrand | a3dab84 | 2018-01-14 09:18:58 +0100 | [diff] [blame] | 998 | // Disabled because of sometimes not working on Windows. |
| 999 | // https://bugs.webrtc.org/34942 |
| 1000 | TEST_P(TransportControllerRTPTransportTest, |
| 1001 | DISABLED_DestroyTransportWithNoReference) { |
Zhi Huang | c08de0f | 2017-12-11 00:20:23 -0800 | [diff] [blame] | 1002 | const std::string transport_name = "transport"; |
| 1003 | webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name); |
| 1004 | webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name); |
| 1005 | EXPECT_NE(nullptr, transport1); |
| 1006 | EXPECT_NE(nullptr, transport2); |
| 1007 | transport_controller_->DestroyTransport(transport_name); |
| 1008 | transport_controller_->DestroyTransport(transport_name); |
| 1009 | #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| 1010 | EXPECT_DEATH(transport1->IsWritable(false), /*error_message=*/""); |
| 1011 | #endif |
| 1012 | } |
| 1013 | |
| 1014 | INSTANTIATE_TEST_CASE_P(TransportControllerTest, |
| 1015 | TransportControllerRTPTransportTest, |
| 1016 | ::testing::Values(RTPTransportType::kSdes, |
| 1017 | RTPTransportType::kDtlsSrtp)); |
| 1018 | |
Zhi Huang | b526158 | 2017-09-29 10:51:43 -0700 | [diff] [blame] | 1019 | } // namespace cricket |