1 /*
2 * Copyright 2019 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 <cstdint>
12 #include <memory>
13
14 #include "api/call/call_factory_interface.h"
15 #include "api/peer_connection_interface.h"
16 #include "api/rtc_event_log/rtc_event_log_factory.h"
17 #include "api/scoped_refptr.h"
18 #include "api/task_queue/default_task_queue_factory.h"
19 #include "api/transport/field_trial_based_config.h"
20 #include "call/simulated_network.h"
21 #include "media/engine/webrtc_media_engine.h"
22 #include "media/engine/webrtc_media_engine_defaults.h"
23 #include "modules/audio_device/include/test_audio_device.h"
24 #include "p2p/base/basic_packet_socket_factory.h"
25 #include "p2p/client/basic_port_allocator.h"
26 #include "pc/peer_connection_wrapper.h"
27 #include "pc/test/mock_peer_connection_observers.h"
28 #include "rtc_base/gunit.h"
29 #include "rtc_base/task_queue_for_test.h"
30 #include "test/gmock.h"
31 #include "test/gtest.h"
32 #include "test/network/network_emulation.h"
33 #include "test/network/network_emulation_manager.h"
34
35 namespace webrtc {
36 namespace test {
37 namespace {
38
39 constexpr int kDefaultTimeoutMs = 1000;
40 constexpr int kMaxAptitude = 32000;
41 constexpr int kSamplingFrequency = 48000;
42 constexpr char kSignalThreadName[] = "signaling_thread";
43
AddIceCandidates(PeerConnectionWrapper * peer,std::vector<const IceCandidateInterface * > candidates)44 bool AddIceCandidates(PeerConnectionWrapper* peer,
45 std::vector<const IceCandidateInterface*> candidates) {
46 bool success = true;
47 for (const auto candidate : candidates) {
48 if (!peer->pc()->AddIceCandidate(candidate)) {
49 success = false;
50 }
51 }
52 return success;
53 }
54
CreatePeerConnectionFactory(rtc::Thread * signaling_thread,rtc::Thread * network_thread)55 rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
56 rtc::Thread* signaling_thread,
57 rtc::Thread* network_thread) {
58 PeerConnectionFactoryDependencies pcf_deps;
59 pcf_deps.task_queue_factory = CreateDefaultTaskQueueFactory();
60 pcf_deps.call_factory = CreateCallFactory();
61 pcf_deps.event_log_factory =
62 std::make_unique<RtcEventLogFactory>(pcf_deps.task_queue_factory.get());
63 pcf_deps.network_thread = network_thread;
64 pcf_deps.signaling_thread = signaling_thread;
65 pcf_deps.trials = std::make_unique<FieldTrialBasedConfig>();
66 cricket::MediaEngineDependencies media_deps;
67 media_deps.task_queue_factory = pcf_deps.task_queue_factory.get();
68 media_deps.adm = TestAudioDeviceModule::Create(
69 media_deps.task_queue_factory,
70 TestAudioDeviceModule::CreatePulsedNoiseCapturer(kMaxAptitude,
71 kSamplingFrequency),
72 TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequency),
73 /*speed=*/1.f);
74 media_deps.trials = pcf_deps.trials.get();
75 SetMediaEngineDefaults(&media_deps);
76 pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps));
77 return CreateModularPeerConnectionFactory(std::move(pcf_deps));
78 }
79
CreatePeerConnection(const rtc::scoped_refptr<PeerConnectionFactoryInterface> & pcf,PeerConnectionObserver * observer,rtc::PacketSocketFactory * packet_socket_factory,rtc::NetworkManager * network_manager,EmulatedTURNServerInterface * turn_server=nullptr)80 rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
81 const rtc::scoped_refptr<PeerConnectionFactoryInterface>& pcf,
82 PeerConnectionObserver* observer,
83 rtc::PacketSocketFactory* packet_socket_factory,
84 rtc::NetworkManager* network_manager,
85 EmulatedTURNServerInterface* turn_server = nullptr) {
86 PeerConnectionDependencies pc_deps(observer);
87 auto port_allocator = std::make_unique<cricket::BasicPortAllocator>(
88 network_manager, packet_socket_factory);
89
90 // This test does not support TCP
91 int flags = cricket::PORTALLOCATOR_DISABLE_TCP;
92 port_allocator->set_flags(port_allocator->flags() | flags);
93
94 pc_deps.allocator = std::move(port_allocator);
95 PeerConnectionInterface::RTCConfiguration rtc_configuration;
96 rtc_configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
97 if (turn_server != nullptr) {
98 webrtc::PeerConnectionInterface::IceServer server;
99 server.username = turn_server->GetIceServerConfig().username;
100 server.password = turn_server->GetIceServerConfig().username;
101 server.urls.push_back(turn_server->GetIceServerConfig().url);
102 rtc_configuration.servers.push_back(server);
103 }
104
105 auto result =
106 pcf->CreatePeerConnectionOrError(rtc_configuration, std::move(pc_deps));
107 if (!result.ok()) {
108 return nullptr;
109 }
110 return result.MoveValue();
111 }
112
113 } // namespace
114
TEST(NetworkEmulationManagerPCTest,Run)115 TEST(NetworkEmulationManagerPCTest, Run) {
116 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
117 signaling_thread->SetName(kSignalThreadName, nullptr);
118 signaling_thread->Start();
119
120 // Setup emulated network
121 NetworkEmulationManagerImpl emulation(
122 TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
123
124 EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
125 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
126 EmulatedNetworkNode* bob_node = emulation.CreateEmulatedNode(
127 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
128 EmulatedEndpoint* alice_endpoint =
129 emulation.CreateEndpoint(EmulatedEndpointConfig());
130 EmulatedEndpoint* bob_endpoint =
131 emulation.CreateEndpoint(EmulatedEndpointConfig());
132 emulation.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
133 emulation.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
134
135 EmulatedNetworkManagerInterface* alice_network =
136 emulation.CreateEmulatedNetworkManagerInterface({alice_endpoint});
137 EmulatedNetworkManagerInterface* bob_network =
138 emulation.CreateEmulatedNetworkManagerInterface({bob_endpoint});
139
140 // Setup peer connections.
141 rtc::scoped_refptr<PeerConnectionFactoryInterface> alice_pcf;
142 rtc::scoped_refptr<PeerConnectionInterface> alice_pc;
143 std::unique_ptr<MockPeerConnectionObserver> alice_observer =
144 std::make_unique<MockPeerConnectionObserver>();
145
146 rtc::scoped_refptr<PeerConnectionFactoryInterface> bob_pcf;
147 rtc::scoped_refptr<PeerConnectionInterface> bob_pc;
148 std::unique_ptr<MockPeerConnectionObserver> bob_observer =
149 std::make_unique<MockPeerConnectionObserver>();
150
151 SendTask(signaling_thread.get(), [&]() {
152 alice_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
153 alice_network->network_thread());
154 alice_pc = CreatePeerConnection(alice_pcf, alice_observer.get(),
155 alice_network->packet_socket_factory(),
156 alice_network->network_manager());
157
158 bob_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
159 bob_network->network_thread());
160 bob_pc = CreatePeerConnection(bob_pcf, bob_observer.get(),
161 bob_network->packet_socket_factory(),
162 bob_network->network_manager());
163 });
164
165 std::unique_ptr<PeerConnectionWrapper> alice =
166 std::make_unique<PeerConnectionWrapper>(alice_pcf, alice_pc,
167 std::move(alice_observer));
168 std::unique_ptr<PeerConnectionWrapper> bob =
169 std::make_unique<PeerConnectionWrapper>(bob_pcf, bob_pc,
170 std::move(bob_observer));
171
172 SendTask(signaling_thread.get(), [&]() {
173 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
174 alice_pcf->CreateAudioSource(cricket::AudioOptions());
175 rtc::scoped_refptr<AudioTrackInterface> track =
176 alice_pcf->CreateAudioTrack("audio", source.get());
177 alice->AddTransceiver(track);
178
179 // Connect peers.
180 ASSERT_TRUE(alice->ExchangeOfferAnswerWith(bob.get()));
181 // Do the SDP negotiation, and also exchange ice candidates.
182 ASSERT_TRUE_WAIT(
183 alice->signaling_state() == PeerConnectionInterface::kStable,
184 kDefaultTimeoutMs);
185 ASSERT_TRUE_WAIT(alice->IsIceGatheringDone(), kDefaultTimeoutMs);
186 ASSERT_TRUE_WAIT(bob->IsIceGatheringDone(), kDefaultTimeoutMs);
187
188 // Connect an ICE candidate pairs.
189 ASSERT_TRUE(
190 AddIceCandidates(bob.get(), alice->observer()->GetAllCandidates()));
191 ASSERT_TRUE(
192 AddIceCandidates(alice.get(), bob->observer()->GetAllCandidates()));
193 // This means that ICE and DTLS are connected.
194 ASSERT_TRUE_WAIT(bob->IsIceConnected(), kDefaultTimeoutMs);
195 ASSERT_TRUE_WAIT(alice->IsIceConnected(), kDefaultTimeoutMs);
196
197 // Close peer connections
198 alice->pc()->Close();
199 bob->pc()->Close();
200
201 // Delete peers.
202 alice.reset();
203 bob.reset();
204 });
205 }
206
TEST(NetworkEmulationManagerPCTest,RunTURN)207 TEST(NetworkEmulationManagerPCTest, RunTURN) {
208 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
209 signaling_thread->SetName(kSignalThreadName, nullptr);
210 signaling_thread->Start();
211
212 // Setup emulated network
213 NetworkEmulationManagerImpl emulation(
214 TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
215
216 EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
217 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
218 EmulatedNetworkNode* bob_node = emulation.CreateEmulatedNode(
219 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
220 EmulatedNetworkNode* turn_node = emulation.CreateEmulatedNode(
221 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
222 EmulatedEndpoint* alice_endpoint =
223 emulation.CreateEndpoint(EmulatedEndpointConfig());
224 EmulatedEndpoint* bob_endpoint =
225 emulation.CreateEndpoint(EmulatedEndpointConfig());
226 EmulatedTURNServerInterface* alice_turn =
227 emulation.CreateTURNServer(EmulatedTURNServerConfig());
228 EmulatedTURNServerInterface* bob_turn =
229 emulation.CreateTURNServer(EmulatedTURNServerConfig());
230
231 emulation.CreateRoute(alice_endpoint, {alice_node},
232 alice_turn->GetClientEndpoint());
233 emulation.CreateRoute(alice_turn->GetClientEndpoint(), {alice_node},
234 alice_endpoint);
235
236 emulation.CreateRoute(bob_endpoint, {bob_node},
237 bob_turn->GetClientEndpoint());
238 emulation.CreateRoute(bob_turn->GetClientEndpoint(), {bob_node},
239 bob_endpoint);
240
241 emulation.CreateRoute(alice_turn->GetPeerEndpoint(), {turn_node},
242 bob_turn->GetPeerEndpoint());
243 emulation.CreateRoute(bob_turn->GetPeerEndpoint(), {turn_node},
244 alice_turn->GetPeerEndpoint());
245
246 EmulatedNetworkManagerInterface* alice_network =
247 emulation.CreateEmulatedNetworkManagerInterface({alice_endpoint});
248 EmulatedNetworkManagerInterface* bob_network =
249 emulation.CreateEmulatedNetworkManagerInterface({bob_endpoint});
250
251 // Setup peer connections.
252 rtc::scoped_refptr<PeerConnectionFactoryInterface> alice_pcf;
253 rtc::scoped_refptr<PeerConnectionInterface> alice_pc;
254 std::unique_ptr<MockPeerConnectionObserver> alice_observer =
255 std::make_unique<MockPeerConnectionObserver>();
256
257 rtc::scoped_refptr<PeerConnectionFactoryInterface> bob_pcf;
258 rtc::scoped_refptr<PeerConnectionInterface> bob_pc;
259 std::unique_ptr<MockPeerConnectionObserver> bob_observer =
260 std::make_unique<MockPeerConnectionObserver>();
261
262 SendTask(signaling_thread.get(), [&]() {
263 alice_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
264 alice_network->network_thread());
265 alice_pc = CreatePeerConnection(
266 alice_pcf, alice_observer.get(), alice_network->packet_socket_factory(),
267 alice_network->network_manager(), alice_turn);
268
269 bob_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
270 bob_network->network_thread());
271 bob_pc = CreatePeerConnection(bob_pcf, bob_observer.get(),
272 bob_network->packet_socket_factory(),
273 bob_network->network_manager(), bob_turn);
274 });
275
276 std::unique_ptr<PeerConnectionWrapper> alice =
277 std::make_unique<PeerConnectionWrapper>(alice_pcf, alice_pc,
278 std::move(alice_observer));
279 std::unique_ptr<PeerConnectionWrapper> bob =
280 std::make_unique<PeerConnectionWrapper>(bob_pcf, bob_pc,
281 std::move(bob_observer));
282
283 SendTask(signaling_thread.get(), [&]() {
284 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
285 alice_pcf->CreateAudioSource(cricket::AudioOptions());
286 rtc::scoped_refptr<AudioTrackInterface> track =
287 alice_pcf->CreateAudioTrack("audio", source.get());
288 alice->AddTransceiver(track);
289
290 // Connect peers.
291 ASSERT_TRUE(alice->ExchangeOfferAnswerWith(bob.get()));
292 // Do the SDP negotiation, and also exchange ice candidates.
293 ASSERT_TRUE_WAIT(
294 alice->signaling_state() == PeerConnectionInterface::kStable,
295 kDefaultTimeoutMs);
296 ASSERT_TRUE_WAIT(alice->IsIceGatheringDone(), kDefaultTimeoutMs);
297 ASSERT_TRUE_WAIT(bob->IsIceGatheringDone(), kDefaultTimeoutMs);
298
299 // Connect an ICE candidate pairs.
300 ASSERT_TRUE(
301 AddIceCandidates(bob.get(), alice->observer()->GetAllCandidates()));
302 ASSERT_TRUE(
303 AddIceCandidates(alice.get(), bob->observer()->GetAllCandidates()));
304 // This means that ICE and DTLS are connected.
305 ASSERT_TRUE_WAIT(bob->IsIceConnected(), kDefaultTimeoutMs);
306 ASSERT_TRUE_WAIT(alice->IsIceConnected(), kDefaultTimeoutMs);
307
308 // Close peer connections
309 alice->pc()->Close();
310 bob->pc()->Close();
311
312 // Delete peers.
313 alice.reset();
314 bob.reset();
315 });
316 }
317
318 } // namespace test
319 } // namespace webrtc
320