blob: c86aa1a2bb55be7b491a6c20e0e72f1104e03667 [file] [log] [blame]
Qingsi Wang1b368942018-06-13 13:54:08 -07001/*
2 * Copyright 2018 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#include <memory>
13#include <string>
14#include <vector>
15
Mirko Bonadeid9708072019-01-25 20:26:48 +010016#include "api/scoped_refptr.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "p2p/base/fake_port_allocator.h"
18#include "p2p/base/mock_ice_transport.h"
19#include "p2p/base/p2p_constants.h"
Qingsi Wang1b368942018-06-13 13:54:08 -070020#include "p2p/base/port.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "p2p/base/regathering_controller.h"
22#include "p2p/base/stun_server.h"
Qingsi Wang1b368942018-06-13 13:54:08 -070023#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/ref_counted_object.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/socket_address.h"
Qingsi Wang1b368942018-06-13 13:54:08 -070026#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/virtual_socket_server.h"
Qingsi Wang1b368942018-06-13 13:54:08 -070028
29namespace {
30
31const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
32 cricket::PORTALLOCATOR_DISABLE_RELAY |
33 cricket::PORTALLOCATOR_DISABLE_TCP;
34// The address of the public STUN server.
35const rtc::SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
36// The addresses for the public TURN server.
37const rtc::SocketAddress kTurnUdpIntAddr("99.99.99.3",
38 cricket::STUN_SERVER_PORT);
39const cricket::RelayCredentials kRelayCredentials("test", "test");
40const char kIceUfrag[] = "UF00";
41const char kIcePwd[] = "TESTICEPWD00000000000000";
42
43} // namespace
44
45namespace webrtc {
46
Mirko Bonadei6a489f22019-04-09 15:11:12 +020047class RegatheringControllerTest : public ::testing::Test,
Qingsi Wang1b368942018-06-13 13:54:08 -070048 public sigslot::has_slots<> {
49 public:
50 RegatheringControllerTest()
51 : vss_(new rtc::VirtualSocketServer()),
52 thread_(vss_.get()),
53 ice_transport_(new cricket::MockIceTransport()),
54 allocator_(
55 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +020056 BasicRegatheringController::Config regathering_config(absl::nullopt, 0);
Qingsi Wang1b368942018-06-13 13:54:08 -070057 regathering_controller_.reset(new BasicRegatheringController(
58 regathering_config, ice_transport_.get(), rtc::Thread::Current()));
59 }
60
61 // Initializes the allocator and gathers candidates once by StartGettingPorts.
62 void InitializeAndGatherOnce() {
63 cricket::ServerAddresses stun_servers;
64 stun_servers.insert(kStunAddr);
65 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
66 turn_server.credentials = kRelayCredentials;
67 turn_server.ports.push_back(
68 cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP));
69 std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);
70 allocator_->set_flags(kOnlyLocalPorts);
71 allocator_->SetConfiguration(stun_servers, turn_servers, 0 /* pool size */,
72 false /* prune turn ports */);
73 allocator_session_ = allocator_->CreateSession(
74 "test", cricket::ICE_CANDIDATE_COMPONENT_RTP, kIceUfrag, kIcePwd);
75 // The gathering will take place on the current thread and the following
76 // call of StartGettingPorts is blocking. We will not ClearGettingPorts
77 // prematurely.
78 allocator_session_->StartGettingPorts();
79 allocator_session_->SignalIceRegathering.connect(
80 this, &RegatheringControllerTest::OnIceRegathering);
81 regathering_controller_->set_allocator_session(allocator_session_.get());
82 }
83
84 // The regathering controller is initialized with the allocator session
85 // cleared. Only after clearing the session, we would be able to regather. See
86 // the comments for BasicRegatheringController in regatheringcontroller.h.
87 void InitializeAndGatherOnceWithSessionCleared() {
88 InitializeAndGatherOnce();
89 allocator_session_->ClearGettingPorts();
90 }
91
92 void OnIceRegathering(cricket::PortAllocatorSession* allocator_session,
93 cricket::IceRegatheringReason reason) {
94 ++count_[reason];
95 }
96
97 int GetRegatheringReasonCount(cricket::IceRegatheringReason reason) {
98 return count_[reason];
99 }
100
101 BasicRegatheringController* regathering_controller() {
102 return regathering_controller_.get();
103 }
104
105 private:
106 std::unique_ptr<rtc::VirtualSocketServer> vss_;
107 rtc::AutoSocketServerThread thread_;
108 std::unique_ptr<cricket::IceTransportInternal> ice_transport_;
109 std::unique_ptr<BasicRegatheringController> regathering_controller_;
110 std::unique_ptr<cricket::PortAllocator> allocator_;
111 std::unique_ptr<cricket::PortAllocatorSession> allocator_session_;
112 std::map<cricket::IceRegatheringReason, int> count_;
113};
114
115// Tests that ICE regathering occurs only if the port allocator session is
116// cleared. A port allocation session is not cleared if the initial gathering is
117// still in progress or the continual gathering is not enabled.
118TEST_F(RegatheringControllerTest,
119 IceRegatheringDoesNotOccurIfSessionNotCleared) {
120 rtc::ScopedFakeClock clock;
121 InitializeAndGatherOnce(); // Session not cleared.
122
123 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
124 BasicRegatheringController::Config config(
125 regather_all_networks_interval_range, 2000);
126 regathering_controller()->SetConfig(config);
127 regathering_controller()->Start();
128 SIMULATED_WAIT(false, 10000, clock);
129 // Expect no regathering in the last 10s.
130 EXPECT_EQ(0, GetRegatheringReasonCount(
131 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
132 EXPECT_EQ(0, GetRegatheringReasonCount(
133 cricket::IceRegatheringReason::NETWORK_FAILURE));
134}
135
136TEST_F(RegatheringControllerTest, IceRegatheringRepeatsAsScheduled) {
137 rtc::ScopedFakeClock clock;
138 InitializeAndGatherOnceWithSessionCleared();
139
140 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
141 BasicRegatheringController::Config config(
142 regather_all_networks_interval_range, 2000);
143 regathering_controller()->SetConfig(config);
144 regathering_controller()->Start();
145 SIMULATED_WAIT(false, 2000 - 1, clock);
146 // Expect no regathering.
147 EXPECT_EQ(0, GetRegatheringReasonCount(
148 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
149 EXPECT_EQ(0, GetRegatheringReasonCount(
150 cricket::IceRegatheringReason::NETWORK_FAILURE));
151 SIMULATED_WAIT(false, 2, clock);
152 // Expect regathering on all networks and on failed networks to happen once
153 // respectively in that last 2s with 2s interval.
154 EXPECT_EQ(1, GetRegatheringReasonCount(
155 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
156 EXPECT_EQ(1, GetRegatheringReasonCount(
157 cricket::IceRegatheringReason::NETWORK_FAILURE));
158 SIMULATED_WAIT(false, 11000, clock);
159 // Expect regathering to happen for another 5 times in 11s with 2s interval.
160 EXPECT_EQ(6, GetRegatheringReasonCount(
161 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
162 EXPECT_EQ(6, GetRegatheringReasonCount(
163 cricket::IceRegatheringReason::NETWORK_FAILURE));
164}
165
166// Tests that the schedule of ICE regathering on all networks can be started
167// when not scheduled initially.
168TEST_F(RegatheringControllerTest,
169 IceRegatheringOnAllNetworksCanBeScheduledAfterStart) {
170 rtc::ScopedFakeClock clock;
171 InitializeAndGatherOnceWithSessionCleared();
172
Danil Chapovalov00c71832018-06-15 15:58:38 +0200173 BasicRegatheringController::Config config(absl::nullopt, 2000);
Qingsi Wang1b368942018-06-13 13:54:08 -0700174 regathering_controller()->SetConfig(config);
175 regathering_controller()->Start();
176 SIMULATED_WAIT(false, 3000, clock);
177 // Expect no regathering on all networks.
178 EXPECT_EQ(0, GetRegatheringReasonCount(
179 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
180 config.regather_on_all_networks_interval_range =
181 rtc::IntervalRange(2000, 2000);
182 regathering_controller()->SetConfig(config);
183 SIMULATED_WAIT(false, 11000, clock);
184 // Expect regathering to happen for 5 times on all networks in the last 11s
185 // with 2s interval.
186 EXPECT_EQ(5, GetRegatheringReasonCount(
187 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
188}
189
190// Tests that ICE regathering on all networks can be canceled by changing the
191// config.
192TEST_F(RegatheringControllerTest, IceRegatheringOnAllNetworksCanBeCanceled) {
193 rtc::ScopedFakeClock clock;
194 InitializeAndGatherOnceWithSessionCleared();
195
196 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
197 BasicRegatheringController::Config config(
198 regather_all_networks_interval_range, 2000);
199 regathering_controller()->SetConfig(config);
200 regathering_controller()->Start();
201 config.regather_on_all_networks_interval_range.reset();
202 // Set the regathering interval range on all networks to nullopt should cancel
203 // the schedule on all networks.
204 regathering_controller()->SetConfig(config);
205 SIMULATED_WAIT(false, 10000, clock);
206 // Expect no regathering on all networks happened in the last 10s.
207 EXPECT_EQ(0, GetRegatheringReasonCount(
208 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
209}
210
211// Tests that canceling the regathering on all networks does not cancel the
212// schedule on failed networks.
213TEST_F(RegatheringControllerTest,
214 CancelingRegatheringOnAllNetworksDoesNotCancelOnFailedNetworks) {
215 rtc::ScopedFakeClock clock;
216 InitializeAndGatherOnceWithSessionCleared();
217
218 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
219 BasicRegatheringController::Config config(
220 regather_all_networks_interval_range, 2000);
221 regathering_controller()->SetConfig(config);
222 regathering_controller()->Start();
223 config.regather_on_all_networks_interval_range =
224 rtc::IntervalRange(20000, 20000);
225 // Canceling and rescheduling the regathering on all networks should not
226 // impact the schedule for failed networks.
227 regathering_controller()->SetConfig(config);
228 SIMULATED_WAIT(false, 11000, clock);
229 // Expect regathering to happen for 5 times for failed networks in the last
230 // 11s with 2s interval.
231 EXPECT_EQ(5, GetRegatheringReasonCount(
232 cricket::IceRegatheringReason::NETWORK_FAILURE));
233}
234
235// Tests that canceling the regathering on failed networks does not cancel the
236// schedule on all networks.
237TEST_F(RegatheringControllerTest,
238 CancelingRegatheringOnFailedNetworksDoesNotCancelOnAllNetworks) {
239 rtc::ScopedFakeClock clock;
240 InitializeAndGatherOnceWithSessionCleared();
241
242 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
243 BasicRegatheringController::Config config(
244 regather_all_networks_interval_range, 2000);
245 regathering_controller()->SetConfig(config);
246 regathering_controller()->Start();
247 config.regather_on_failed_networks_interval = 20000;
248 // Canceling and rescheduling the regathering on failed networks should not
249 // impact the schedule for all networks.
250 regathering_controller()->SetConfig(config);
251 SIMULATED_WAIT(false, 11000, clock);
252 // Expect regathering to happen for 5 times for all networks in the last 11s
253 // with 2s interval.
254 EXPECT_EQ(5, GetRegatheringReasonCount(
255 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
256}
257
258// Tests that the schedule of ICE regathering on all networks can be canceled
259// and replaced by a new recurring schedule.
260TEST_F(RegatheringControllerTest,
261 ScheduleOfIceRegatheringOnAllNetworksCanBeReplaced) {
262 rtc::ScopedFakeClock clock;
263 InitializeAndGatherOnceWithSessionCleared();
264
265 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
266 BasicRegatheringController::Config config(
267 regather_all_networks_interval_range, 2000);
268 regathering_controller()->SetConfig(config);
269 regathering_controller()->Start();
270 config.regather_on_all_networks_interval_range =
271 rtc::IntervalRange(5000, 5000);
272 regathering_controller()->SetConfig(config);
273 SIMULATED_WAIT(false, 3000, clock);
274 // Expect no regathering from the previous schedule.
275 EXPECT_EQ(0, GetRegatheringReasonCount(
276 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
277 SIMULATED_WAIT(false, 11000 - 3000, clock);
278 // Expect regathering to happen twice in the last 11s with 5s interval.
279 EXPECT_EQ(2, GetRegatheringReasonCount(
280 cricket::IceRegatheringReason::OCCASIONAL_REFRESH));
281}
282
283// Tests that the schedule of ICE regathering on failed networks can be canceled
284// and replaced by a new recurring schedule.
285TEST_F(RegatheringControllerTest,
286 ScheduleOfIceRegatheringOnFailedNetworksCanBeReplaced) {
287 rtc::ScopedFakeClock clock;
288 InitializeAndGatherOnceWithSessionCleared();
289
290 rtc::IntervalRange regather_all_networks_interval_range(2000, 2000);
291 BasicRegatheringController::Config config(
292 regather_all_networks_interval_range, 2000);
293 regathering_controller()->SetConfig(config);
294 regathering_controller()->Start();
295 config.regather_on_failed_networks_interval = 5000;
296 regathering_controller()->SetConfig(config);
297 SIMULATED_WAIT(false, 3000, clock);
298 // Expect no regathering from the previous schedule.
299 EXPECT_EQ(0, GetRegatheringReasonCount(
300 cricket::IceRegatheringReason::NETWORK_FAILURE));
301 SIMULATED_WAIT(false, 11000 - 3000, clock);
302 // Expect regathering to happen twice in the last 11s with 5s interval.
303 EXPECT_EQ(2, GetRegatheringReasonCount(
304 cricket::IceRegatheringReason::NETWORK_FAILURE));
305}
306
307} // namespace webrtc