blob: 73ac54e7efedfbd30d31bca04ebbd8b56a16bdb9 [file] [log] [blame]
Artem Titov0774bd92019-01-30 14:26:051/*
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
Danil Chapovalov554f7db2023-11-01 10:08:2014#include "api/enable_media_with_defaults.h"
Artem Titov0774bd92019-01-30 14:26:0515#include "api/peer_connection_interface.h"
Danil Chapovalovf4c7ab12019-05-31 15:03:2716#include "api/rtc_event_log/rtc_event_log_factory.h"
Artem Titov0774bd92019-01-30 14:26:0517#include "api/scoped_refptr.h"
Danil Chapovalovf4c7ab12019-05-31 15:03:2718#include "api/task_queue/default_task_queue_factory.h"
Erik Språngceb44952020-09-22 09:36:3519#include "api/transport/field_trial_based_config.h"
Artem Titov0774bd92019-01-30 14:26:0520#include "call/simulated_network.h"
Artem Titov0774bd92019-01-30 14:26:0521#include "media/engine/webrtc_media_engine.h"
22#include "modules/audio_device/include/test_audio_device.h"
Byoungchan Leed197e0b2022-05-30 14:59:5523#include "p2p/base/basic_packet_socket_factory.h"
Artem Titov0774bd92019-01-30 14:26:0524#include "p2p/client/basic_port_allocator.h"
25#include "pc/peer_connection_wrapper.h"
26#include "pc/test/mock_peer_connection_observers.h"
Artem Titov0774bd92019-01-30 14:26:0527#include "rtc_base/gunit.h"
Danil Chapovalov2aaef452022-08-12 13:55:1128#include "rtc_base/task_queue_for_test.h"
Artem Titov0774bd92019-01-30 14:26:0529#include "test/gmock.h"
30#include "test/gtest.h"
Artem Titov386802e2019-07-05 08:48:1731#include "test/network/network_emulation.h"
32#include "test/network/network_emulation_manager.h"
Artem Titov0774bd92019-01-30 14:26:0533
34namespace webrtc {
35namespace test {
36namespace {
37
38constexpr int kDefaultTimeoutMs = 1000;
39constexpr int kMaxAptitude = 32000;
40constexpr int kSamplingFrequency = 48000;
41constexpr char kSignalThreadName[] = "signaling_thread";
42
43bool AddIceCandidates(PeerConnectionWrapper* peer,
44 std::vector<const IceCandidateInterface*> candidates) {
45 bool success = true;
46 for (const auto candidate : candidates) {
47 if (!peer->pc()->AddIceCandidate(candidate)) {
48 success = false;
49 }
50 }
51 return success;
52}
53
54rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
55 rtc::Thread* signaling_thread,
56 rtc::Thread* network_thread) {
57 PeerConnectionFactoryDependencies pcf_deps;
Danil Chapovalovf4c7ab12019-05-31 15:03:2758 pcf_deps.task_queue_factory = CreateDefaultTaskQueueFactory();
Danil Chapovalov151003d2023-12-07 19:01:0659 pcf_deps.event_log_factory = std::make_unique<RtcEventLogFactory>();
Artem Titov0774bd92019-01-30 14:26:0560 pcf_deps.network_thread = network_thread;
61 pcf_deps.signaling_thread = signaling_thread;
Erik Språngceb44952020-09-22 09:36:3562 pcf_deps.trials = std::make_unique<FieldTrialBasedConfig>();
Danil Chapovalov554f7db2023-11-01 10:08:2063 pcf_deps.adm = TestAudioDeviceModule::Create(
64 pcf_deps.task_queue_factory.get(),
Danil Chapovalovf4c7ab12019-05-31 15:03:2765 TestAudioDeviceModule::CreatePulsedNoiseCapturer(kMaxAptitude,
66 kSamplingFrequency),
67 TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequency),
68 /*speed=*/1.f);
Danil Chapovalov554f7db2023-11-01 10:08:2069 EnableMediaWithDefaults(pcf_deps);
Artem Titov0774bd92019-01-30 14:26:0570 return CreateModularPeerConnectionFactory(std::move(pcf_deps));
71}
72
73rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
74 const rtc::scoped_refptr<PeerConnectionFactoryInterface>& pcf,
75 PeerConnectionObserver* observer,
Byoungchan Leed197e0b2022-05-30 14:59:5576 rtc::PacketSocketFactory* packet_socket_factory,
Jonas Oreland97050112020-11-17 20:30:3377 rtc::NetworkManager* network_manager,
78 EmulatedTURNServerInterface* turn_server = nullptr) {
Artem Titov0774bd92019-01-30 14:26:0579 PeerConnectionDependencies pc_deps(observer);
Byoungchan Leed197e0b2022-05-30 14:59:5580 auto port_allocator = std::make_unique<cricket::BasicPortAllocator>(
81 network_manager, packet_socket_factory);
Artem Titov0774bd92019-01-30 14:26:0582
83 // This test does not support TCP
84 int flags = cricket::PORTALLOCATOR_DISABLE_TCP;
85 port_allocator->set_flags(port_allocator->flags() | flags);
86
87 pc_deps.allocator = std::move(port_allocator);
88 PeerConnectionInterface::RTCConfiguration rtc_configuration;
89 rtc_configuration.sdp_semantics = SdpSemantics::kUnifiedPlan;
Jonas Oreland97050112020-11-17 20:30:3390 if (turn_server != nullptr) {
91 webrtc::PeerConnectionInterface::IceServer server;
92 server.username = turn_server->GetIceServerConfig().username;
93 server.password = turn_server->GetIceServerConfig().username;
94 server.urls.push_back(turn_server->GetIceServerConfig().url);
95 rtc_configuration.servers.push_back(server);
96 }
Artem Titov0774bd92019-01-30 14:26:0597
Harald Alvestrandf33f7a22021-05-09 14:58:5798 auto result =
99 pcf->CreatePeerConnectionOrError(rtc_configuration, std::move(pc_deps));
100 if (!result.ok()) {
101 return nullptr;
102 }
103 return result.MoveValue();
Artem Titov0774bd92019-01-30 14:26:05104}
105
106} // namespace
107
108TEST(NetworkEmulationManagerPCTest, Run) {
109 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
110 signaling_thread->SetName(kSignalThreadName, nullptr);
111 signaling_thread->Start();
112
113 // Setup emulated network
Artem Titovb41568b2022-11-11 22:14:30114 NetworkEmulationManagerImpl emulation(
115 TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
Artem Titov0774bd92019-01-30 14:26:05116
Artem Titovf84b95d2019-03-13 13:08:49117 EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 15:06:18118 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovf84b95d2019-03-13 13:08:49119 EmulatedNetworkNode* bob_node = emulation.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 15:06:18120 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovaba8dc22019-03-11 09:08:40121 EmulatedEndpoint* alice_endpoint =
Artem Titovf84b95d2019-03-13 13:08:49122 emulation.CreateEndpoint(EmulatedEndpointConfig());
Artem Titovaba8dc22019-03-11 09:08:40123 EmulatedEndpoint* bob_endpoint =
Artem Titovf84b95d2019-03-13 13:08:49124 emulation.CreateEndpoint(EmulatedEndpointConfig());
125 emulation.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
126 emulation.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
Artem Titov0774bd92019-01-30 14:26:05127
Artem Titove5cc85b2019-03-28 11:11:09128 EmulatedNetworkManagerInterface* alice_network =
129 emulation.CreateEmulatedNetworkManagerInterface({alice_endpoint});
130 EmulatedNetworkManagerInterface* bob_network =
131 emulation.CreateEmulatedNetworkManagerInterface({bob_endpoint});
Artem Titov0774bd92019-01-30 14:26:05132
133 // Setup peer connections.
134 rtc::scoped_refptr<PeerConnectionFactoryInterface> alice_pcf;
135 rtc::scoped_refptr<PeerConnectionInterface> alice_pc;
136 std::unique_ptr<MockPeerConnectionObserver> alice_observer =
Mirko Bonadei317a1f02019-09-17 15:06:18137 std::make_unique<MockPeerConnectionObserver>();
Artem Titov0774bd92019-01-30 14:26:05138
139 rtc::scoped_refptr<PeerConnectionFactoryInterface> bob_pcf;
140 rtc::scoped_refptr<PeerConnectionInterface> bob_pc;
141 std::unique_ptr<MockPeerConnectionObserver> bob_observer =
Mirko Bonadei317a1f02019-09-17 15:06:18142 std::make_unique<MockPeerConnectionObserver>();
Artem Titov0774bd92019-01-30 14:26:05143
Danil Chapovalov2aaef452022-08-12 13:55:11144 SendTask(signaling_thread.get(), [&]() {
Artem Titov0774bd92019-01-30 14:26:05145 alice_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
Artem Titove5cc85b2019-03-28 11:11:09146 alice_network->network_thread());
Artem Titov0774bd92019-01-30 14:26:05147 alice_pc = CreatePeerConnection(alice_pcf, alice_observer.get(),
Byoungchan Leed197e0b2022-05-30 14:59:55148 alice_network->packet_socket_factory(),
Artem Titove5cc85b2019-03-28 11:11:09149 alice_network->network_manager());
Artem Titov0774bd92019-01-30 14:26:05150
Artem Titove5cc85b2019-03-28 11:11:09151 bob_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
152 bob_network->network_thread());
153 bob_pc = CreatePeerConnection(bob_pcf, bob_observer.get(),
Byoungchan Leed197e0b2022-05-30 14:59:55154 bob_network->packet_socket_factory(),
Artem Titove5cc85b2019-03-28 11:11:09155 bob_network->network_manager());
Artem Titov0774bd92019-01-30 14:26:05156 });
157
158 std::unique_ptr<PeerConnectionWrapper> alice =
Mirko Bonadei317a1f02019-09-17 15:06:18159 std::make_unique<PeerConnectionWrapper>(alice_pcf, alice_pc,
160 std::move(alice_observer));
Artem Titov0774bd92019-01-30 14:26:05161 std::unique_ptr<PeerConnectionWrapper> bob =
Mirko Bonadei317a1f02019-09-17 15:06:18162 std::make_unique<PeerConnectionWrapper>(bob_pcf, bob_pc,
163 std::move(bob_observer));
Artem Titov0774bd92019-01-30 14:26:05164
Danil Chapovalov2aaef452022-08-12 13:55:11165 SendTask(signaling_thread.get(), [&]() {
Artem Titovb6458e12019-01-31 13:42:57166 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
167 alice_pcf->CreateAudioSource(cricket::AudioOptions());
168 rtc::scoped_refptr<AudioTrackInterface> track =
Niels Möller3c4f9c12022-04-22 09:14:34169 alice_pcf->CreateAudioTrack("audio", source.get());
Artem Titovb6458e12019-01-31 13:42:57170 alice->AddTransceiver(track);
Artem Titov0774bd92019-01-30 14:26:05171
172 // Connect peers.
173 ASSERT_TRUE(alice->ExchangeOfferAnswerWith(bob.get()));
174 // Do the SDP negotiation, and also exchange ice candidates.
175 ASSERT_TRUE_WAIT(
176 alice->signaling_state() == PeerConnectionInterface::kStable,
177 kDefaultTimeoutMs);
178 ASSERT_TRUE_WAIT(alice->IsIceGatheringDone(), kDefaultTimeoutMs);
179 ASSERT_TRUE_WAIT(bob->IsIceGatheringDone(), kDefaultTimeoutMs);
180
181 // Connect an ICE candidate pairs.
182 ASSERT_TRUE(
183 AddIceCandidates(bob.get(), alice->observer()->GetAllCandidates()));
184 ASSERT_TRUE(
185 AddIceCandidates(alice.get(), bob->observer()->GetAllCandidates()));
186 // This means that ICE and DTLS are connected.
187 ASSERT_TRUE_WAIT(bob->IsIceConnected(), kDefaultTimeoutMs);
188 ASSERT_TRUE_WAIT(alice->IsIceConnected(), kDefaultTimeoutMs);
189
Artem Titov0774bd92019-01-30 14:26:05190 // Close peer connections
191 alice->pc()->Close();
192 bob->pc()->Close();
193
194 // Delete peers.
195 alice.reset();
196 bob.reset();
197 });
Artem Titov0774bd92019-01-30 14:26:05198}
199
Jonas Oreland97050112020-11-17 20:30:33200TEST(NetworkEmulationManagerPCTest, RunTURN) {
201 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
202 signaling_thread->SetName(kSignalThreadName, nullptr);
203 signaling_thread->Start();
204
205 // Setup emulated network
Artem Titovb41568b2022-11-11 22:14:30206 NetworkEmulationManagerImpl emulation(
207 TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
Jonas Oreland97050112020-11-17 20:30:33208
209 EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
210 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
211 EmulatedNetworkNode* bob_node = emulation.CreateEmulatedNode(
212 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
213 EmulatedNetworkNode* turn_node = emulation.CreateEmulatedNode(
214 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
215 EmulatedEndpoint* alice_endpoint =
216 emulation.CreateEndpoint(EmulatedEndpointConfig());
217 EmulatedEndpoint* bob_endpoint =
218 emulation.CreateEndpoint(EmulatedEndpointConfig());
219 EmulatedTURNServerInterface* alice_turn =
220 emulation.CreateTURNServer(EmulatedTURNServerConfig());
221 EmulatedTURNServerInterface* bob_turn =
222 emulation.CreateTURNServer(EmulatedTURNServerConfig());
223
224 emulation.CreateRoute(alice_endpoint, {alice_node},
225 alice_turn->GetClientEndpoint());
226 emulation.CreateRoute(alice_turn->GetClientEndpoint(), {alice_node},
227 alice_endpoint);
228
229 emulation.CreateRoute(bob_endpoint, {bob_node},
230 bob_turn->GetClientEndpoint());
231 emulation.CreateRoute(bob_turn->GetClientEndpoint(), {bob_node},
232 bob_endpoint);
233
234 emulation.CreateRoute(alice_turn->GetPeerEndpoint(), {turn_node},
235 bob_turn->GetPeerEndpoint());
236 emulation.CreateRoute(bob_turn->GetPeerEndpoint(), {turn_node},
237 alice_turn->GetPeerEndpoint());
238
239 EmulatedNetworkManagerInterface* alice_network =
240 emulation.CreateEmulatedNetworkManagerInterface({alice_endpoint});
241 EmulatedNetworkManagerInterface* bob_network =
242 emulation.CreateEmulatedNetworkManagerInterface({bob_endpoint});
243
244 // Setup peer connections.
245 rtc::scoped_refptr<PeerConnectionFactoryInterface> alice_pcf;
246 rtc::scoped_refptr<PeerConnectionInterface> alice_pc;
247 std::unique_ptr<MockPeerConnectionObserver> alice_observer =
248 std::make_unique<MockPeerConnectionObserver>();
249
250 rtc::scoped_refptr<PeerConnectionFactoryInterface> bob_pcf;
251 rtc::scoped_refptr<PeerConnectionInterface> bob_pc;
252 std::unique_ptr<MockPeerConnectionObserver> bob_observer =
253 std::make_unique<MockPeerConnectionObserver>();
254
Danil Chapovalov2aaef452022-08-12 13:55:11255 SendTask(signaling_thread.get(), [&]() {
Jonas Oreland97050112020-11-17 20:30:33256 alice_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
257 alice_network->network_thread());
Byoungchan Leed197e0b2022-05-30 14:59:55258 alice_pc = CreatePeerConnection(
259 alice_pcf, alice_observer.get(), alice_network->packet_socket_factory(),
260 alice_network->network_manager(), alice_turn);
Jonas Oreland97050112020-11-17 20:30:33261
262 bob_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
263 bob_network->network_thread());
264 bob_pc = CreatePeerConnection(bob_pcf, bob_observer.get(),
Byoungchan Leed197e0b2022-05-30 14:59:55265 bob_network->packet_socket_factory(),
Jonas Oreland97050112020-11-17 20:30:33266 bob_network->network_manager(), bob_turn);
267 });
268
269 std::unique_ptr<PeerConnectionWrapper> alice =
270 std::make_unique<PeerConnectionWrapper>(alice_pcf, alice_pc,
271 std::move(alice_observer));
272 std::unique_ptr<PeerConnectionWrapper> bob =
273 std::make_unique<PeerConnectionWrapper>(bob_pcf, bob_pc,
274 std::move(bob_observer));
275
Danil Chapovalov2aaef452022-08-12 13:55:11276 SendTask(signaling_thread.get(), [&]() {
Jonas Oreland97050112020-11-17 20:30:33277 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
278 alice_pcf->CreateAudioSource(cricket::AudioOptions());
279 rtc::scoped_refptr<AudioTrackInterface> track =
Niels Möller3c4f9c12022-04-22 09:14:34280 alice_pcf->CreateAudioTrack("audio", source.get());
Jonas Oreland97050112020-11-17 20:30:33281 alice->AddTransceiver(track);
282
283 // Connect peers.
284 ASSERT_TRUE(alice->ExchangeOfferAnswerWith(bob.get()));
285 // Do the SDP negotiation, and also exchange ice candidates.
286 ASSERT_TRUE_WAIT(
287 alice->signaling_state() == PeerConnectionInterface::kStable,
288 kDefaultTimeoutMs);
289 ASSERT_TRUE_WAIT(alice->IsIceGatheringDone(), kDefaultTimeoutMs);
290 ASSERT_TRUE_WAIT(bob->IsIceGatheringDone(), kDefaultTimeoutMs);
291
292 // Connect an ICE candidate pairs.
293 ASSERT_TRUE(
294 AddIceCandidates(bob.get(), alice->observer()->GetAllCandidates()));
295 ASSERT_TRUE(
296 AddIceCandidates(alice.get(), bob->observer()->GetAllCandidates()));
297 // This means that ICE and DTLS are connected.
298 ASSERT_TRUE_WAIT(bob->IsIceConnected(), kDefaultTimeoutMs);
299 ASSERT_TRUE_WAIT(alice->IsIceConnected(), kDefaultTimeoutMs);
300
301 // Close peer connections
302 alice->pc()->Close();
303 bob->pc()->Close();
304
305 // Delete peers.
306 alice.reset();
307 bob.reset();
308 });
309}
310
Artem Titov0774bd92019-01-30 14:26:05311} // namespace test
312} // namespace webrtc