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 "call/simulated_network.h"
20 #include "media/engine/webrtc_media_engine.h"
21 #include "media/engine/webrtc_media_engine_defaults.h"
22 #include "modules/audio_device/include/test_audio_device.h"
23 #include "p2p/client/basic_port_allocator.h"
24 #include "pc/peer_connection_wrapper.h"
25 #include "pc/test/mock_peer_connection_observers.h"
26 #include "rtc_base/gunit.h"
27 #include "test/gmock.h"
28 #include "test/gtest.h"
29 #include "test/network/network_emulation.h"
30 #include "test/network/network_emulation_manager.h"
31
32 namespace webrtc {
33 namespace test {
34 namespace {
35
36 constexpr int kDefaultTimeoutMs = 1000;
37 constexpr int kMaxAptitude = 32000;
38 constexpr int kSamplingFrequency = 48000;
39 constexpr char kSignalThreadName[] = "signaling_thread";
40
AddIceCandidates(PeerConnectionWrapper * peer,std::vector<const IceCandidateInterface * > candidates)41 bool AddIceCandidates(PeerConnectionWrapper* peer,
42 std::vector<const IceCandidateInterface*> candidates) {
43 bool success = true;
44 for (const auto candidate : candidates) {
45 if (!peer->pc()->AddIceCandidate(candidate)) {
46 success = false;
47 }
48 }
49 return success;
50 }
51
CreatePeerConnectionFactory(rtc::Thread * signaling_thread,rtc::Thread * network_thread)52 rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
53 rtc::Thread* signaling_thread,
54 rtc::Thread* network_thread) {
55 PeerConnectionFactoryDependencies pcf_deps;
56 pcf_deps.task_queue_factory = CreateDefaultTaskQueueFactory();
57 pcf_deps.call_factory = CreateCallFactory();
58 pcf_deps.event_log_factory =
59 std::make_unique<RtcEventLogFactory>(pcf_deps.task_queue_factory.get());
60 pcf_deps.network_thread = network_thread;
61 pcf_deps.signaling_thread = signaling_thread;
62 cricket::MediaEngineDependencies media_deps;
63 media_deps.task_queue_factory = pcf_deps.task_queue_factory.get();
64 media_deps.adm = TestAudioDeviceModule::Create(
65 media_deps.task_queue_factory,
66 TestAudioDeviceModule::CreatePulsedNoiseCapturer(kMaxAptitude,
67 kSamplingFrequency),
68 TestAudioDeviceModule::CreateDiscardRenderer(kSamplingFrequency),
69 /*speed=*/1.f);
70 SetMediaEngineDefaults(&media_deps);
71 pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps));
72 return CreateModularPeerConnectionFactory(std::move(pcf_deps));
73 }
74
CreatePeerConnection(const rtc::scoped_refptr<PeerConnectionFactoryInterface> & pcf,PeerConnectionObserver * observer,rtc::NetworkManager * network_manager)75 rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
76 const rtc::scoped_refptr<PeerConnectionFactoryInterface>& pcf,
77 PeerConnectionObserver* observer,
78 rtc::NetworkManager* network_manager) {
79 PeerConnectionDependencies pc_deps(observer);
80 auto port_allocator =
81 std::make_unique<cricket::BasicPortAllocator>(network_manager);
82
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;
90
91 return pcf->CreatePeerConnection(rtc_configuration, std::move(pc_deps));
92 }
93
94 } // namespace
95
TEST(NetworkEmulationManagerPCTest,Run)96 TEST(NetworkEmulationManagerPCTest, Run) {
97 std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
98 signaling_thread->SetName(kSignalThreadName, nullptr);
99 signaling_thread->Start();
100
101 // Setup emulated network
102 NetworkEmulationManagerImpl emulation(TimeMode::kRealTime);
103
104 EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
105 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
106 EmulatedNetworkNode* bob_node = emulation.CreateEmulatedNode(
107 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
108 EmulatedEndpoint* alice_endpoint =
109 emulation.CreateEndpoint(EmulatedEndpointConfig());
110 EmulatedEndpoint* bob_endpoint =
111 emulation.CreateEndpoint(EmulatedEndpointConfig());
112 emulation.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
113 emulation.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
114
115 EmulatedNetworkManagerInterface* alice_network =
116 emulation.CreateEmulatedNetworkManagerInterface({alice_endpoint});
117 EmulatedNetworkManagerInterface* bob_network =
118 emulation.CreateEmulatedNetworkManagerInterface({bob_endpoint});
119
120 // Setup peer connections.
121 rtc::scoped_refptr<PeerConnectionFactoryInterface> alice_pcf;
122 rtc::scoped_refptr<PeerConnectionInterface> alice_pc;
123 std::unique_ptr<MockPeerConnectionObserver> alice_observer =
124 std::make_unique<MockPeerConnectionObserver>();
125
126 rtc::scoped_refptr<PeerConnectionFactoryInterface> bob_pcf;
127 rtc::scoped_refptr<PeerConnectionInterface> bob_pc;
128 std::unique_ptr<MockPeerConnectionObserver> bob_observer =
129 std::make_unique<MockPeerConnectionObserver>();
130
131 signaling_thread->Invoke<void>(RTC_FROM_HERE, [&]() {
132 alice_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
133 alice_network->network_thread());
134 alice_pc = CreatePeerConnection(alice_pcf, alice_observer.get(),
135 alice_network->network_manager());
136
137 bob_pcf = CreatePeerConnectionFactory(signaling_thread.get(),
138 bob_network->network_thread());
139 bob_pc = CreatePeerConnection(bob_pcf, bob_observer.get(),
140 bob_network->network_manager());
141 });
142
143 std::unique_ptr<PeerConnectionWrapper> alice =
144 std::make_unique<PeerConnectionWrapper>(alice_pcf, alice_pc,
145 std::move(alice_observer));
146 std::unique_ptr<PeerConnectionWrapper> bob =
147 std::make_unique<PeerConnectionWrapper>(bob_pcf, bob_pc,
148 std::move(bob_observer));
149
150 signaling_thread->Invoke<void>(RTC_FROM_HERE, [&]() {
151 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
152 alice_pcf->CreateAudioSource(cricket::AudioOptions());
153 rtc::scoped_refptr<AudioTrackInterface> track =
154 alice_pcf->CreateAudioTrack("audio", source);
155 alice->AddTransceiver(track);
156
157 // Connect peers.
158 ASSERT_TRUE(alice->ExchangeOfferAnswerWith(bob.get()));
159 // Do the SDP negotiation, and also exchange ice candidates.
160 ASSERT_TRUE_WAIT(
161 alice->signaling_state() == PeerConnectionInterface::kStable,
162 kDefaultTimeoutMs);
163 ASSERT_TRUE_WAIT(alice->IsIceGatheringDone(), kDefaultTimeoutMs);
164 ASSERT_TRUE_WAIT(bob->IsIceGatheringDone(), kDefaultTimeoutMs);
165
166 // Connect an ICE candidate pairs.
167 ASSERT_TRUE(
168 AddIceCandidates(bob.get(), alice->observer()->GetAllCandidates()));
169 ASSERT_TRUE(
170 AddIceCandidates(alice.get(), bob->observer()->GetAllCandidates()));
171 // This means that ICE and DTLS are connected.
172 ASSERT_TRUE_WAIT(bob->IsIceConnected(), kDefaultTimeoutMs);
173 ASSERT_TRUE_WAIT(alice->IsIceConnected(), kDefaultTimeoutMs);
174
175 // Close peer connections
176 alice->pc()->Close();
177 bob->pc()->Close();
178
179 // Delete peers.
180 alice.reset();
181 bob.reset();
182 });
183 }
184
185 } // namespace test
186 } // namespace webrtc
187