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