xref: /aosp_15_r20/external/webrtc/pc/peer_connection_rampup_tests.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include <memory>
12*d9f75844SAndroid Build Coastguard Worker #include <string>
13*d9f75844SAndroid Build Coastguard Worker #include <utility>
14*d9f75844SAndroid Build Coastguard Worker #include <vector>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/audio_options.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/jsep.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/media_stream_interface.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtc_stats.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtc_stats_report.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtcstats_objects.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/test/metrics/global_metrics_logger_and_exporter.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/test/metrics/metric.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
34*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
35*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
36*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
37*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_interface.h"
38*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_turn_server.h"
39*d9f75844SAndroid Build Coastguard Worker #include "p2p/client/basic_port_allocator.h"
40*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection.h"
41*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_wrapper.h"
42*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_audio_capture_module.h"
43*d9f75844SAndroid Build Coastguard Worker #include "pc/test/frame_generator_capturer_video_track_source.h"
44*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
45*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
46*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_network.h"
47*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/firewall_socket_server.h"
48*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
49*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
50*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_address.h"
51*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_factory.h"
52*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_certificate.h"
53*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
54*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/test_certificate_verifier.h"
55*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
56*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
57*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
58*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
59*d9f75844SAndroid Build Coastguard Worker 
60*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
61*d9f75844SAndroid Build Coastguard Worker namespace {
62*d9f75844SAndroid Build Coastguard Worker 
63*d9f75844SAndroid Build Coastguard Worker using ::webrtc::test::GetGlobalMetricsLogger;
64*d9f75844SAndroid Build Coastguard Worker using ::webrtc::test::ImprovementDirection;
65*d9f75844SAndroid Build Coastguard Worker using ::webrtc::test::Unit;
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker static const int kDefaultTestTimeMs = 15000;
68*d9f75844SAndroid Build Coastguard Worker static const int kRampUpTimeMs = 5000;
69*d9f75844SAndroid Build Coastguard Worker static const int kPollIntervalTimeMs = 50;
70*d9f75844SAndroid Build Coastguard Worker static const int kDefaultTimeoutMs = 10000;
71*d9f75844SAndroid Build Coastguard Worker static const rtc::SocketAddress kDefaultLocalAddress("1.1.1.1", 0);
72*d9f75844SAndroid Build Coastguard Worker static const char kTurnInternalAddress[] = "88.88.88.0";
73*d9f75844SAndroid Build Coastguard Worker static const char kTurnExternalAddress[] = "88.88.88.1";
74*d9f75844SAndroid Build Coastguard Worker static const int kTurnInternalPort = 3478;
75*d9f75844SAndroid Build Coastguard Worker static const int kTurnExternalPort = 0;
76*d9f75844SAndroid Build Coastguard Worker // The video's configured max bitrate in webrtcvideoengine.cc is 1.7 Mbps.
77*d9f75844SAndroid Build Coastguard Worker // Setting the network bandwidth to 1 Mbps allows the video's bitrate to push
78*d9f75844SAndroid Build Coastguard Worker // the network's limitations.
79*d9f75844SAndroid Build Coastguard Worker static const int kNetworkBandwidth = 1000000;
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker }  // namespace
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
84*d9f75844SAndroid Build Coastguard Worker 
85*d9f75844SAndroid Build Coastguard Worker // This is an end to end test to verify that BWE is functioning when setting
86*d9f75844SAndroid Build Coastguard Worker // up a one to one call at the PeerConnection level. The intention of the test
87*d9f75844SAndroid Build Coastguard Worker // is to catch potential regressions for different ICE path configurations. The
88*d9f75844SAndroid Build Coastguard Worker // test uses a VirtualSocketServer for it's underlying simulated network and
89*d9f75844SAndroid Build Coastguard Worker // fake audio and video sources. The test is based upon rampup_tests.cc, but
90*d9f75844SAndroid Build Coastguard Worker // instead is at the PeerConnection level and uses a different fake network
91*d9f75844SAndroid Build Coastguard Worker // (rampup_tests.cc uses SimulatedNetwork). In the future, this test could
92*d9f75844SAndroid Build Coastguard Worker // potentially test different network conditions and test video quality as well
93*d9f75844SAndroid Build Coastguard Worker // (video_quality_test.cc does this, but at the call level).
94*d9f75844SAndroid Build Coastguard Worker //
95*d9f75844SAndroid Build Coastguard Worker // The perf test results are printed using the perf test support. If the
96*d9f75844SAndroid Build Coastguard Worker // isolated_script_test_perf_output flag is specified in test_main.cc, then
97*d9f75844SAndroid Build Coastguard Worker // the results are written to a JSON formatted file for the Chrome perf
98*d9f75844SAndroid Build Coastguard Worker // dashboard. Since this test is a webrtc_perf_test, it will be run in the perf
99*d9f75844SAndroid Build Coastguard Worker // console every webrtc commit.
100*d9f75844SAndroid Build Coastguard Worker class PeerConnectionWrapperForRampUpTest : public PeerConnectionWrapper {
101*d9f75844SAndroid Build Coastguard Worker  public:
102*d9f75844SAndroid Build Coastguard Worker   using PeerConnectionWrapper::PeerConnectionWrapper;
103*d9f75844SAndroid Build Coastguard Worker 
PeerConnectionWrapperForRampUpTest(rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,rtc::scoped_refptr<PeerConnectionInterface> pc,std::unique_ptr<MockPeerConnectionObserver> observer)104*d9f75844SAndroid Build Coastguard Worker   PeerConnectionWrapperForRampUpTest(
105*d9f75844SAndroid Build Coastguard Worker       rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
106*d9f75844SAndroid Build Coastguard Worker       rtc::scoped_refptr<PeerConnectionInterface> pc,
107*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<MockPeerConnectionObserver> observer)
108*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionWrapper::PeerConnectionWrapper(pc_factory,
109*d9f75844SAndroid Build Coastguard Worker                                                      pc,
110*d9f75844SAndroid Build Coastguard Worker                                                      std::move(observer)) {}
111*d9f75844SAndroid Build Coastguard Worker 
AddIceCandidates(std::vector<const IceCandidateInterface * > candidates)112*d9f75844SAndroid Build Coastguard Worker   bool AddIceCandidates(std::vector<const IceCandidateInterface*> candidates) {
113*d9f75844SAndroid Build Coastguard Worker     bool success = true;
114*d9f75844SAndroid Build Coastguard Worker     for (const auto candidate : candidates) {
115*d9f75844SAndroid Build Coastguard Worker       if (!pc()->AddIceCandidate(candidate)) {
116*d9f75844SAndroid Build Coastguard Worker         success = false;
117*d9f75844SAndroid Build Coastguard Worker       }
118*d9f75844SAndroid Build Coastguard Worker     }
119*d9f75844SAndroid Build Coastguard Worker     return success;
120*d9f75844SAndroid Build Coastguard Worker   }
121*d9f75844SAndroid Build Coastguard Worker 
CreateLocalVideoTrack(FrameGeneratorCapturerVideoTrackSource::Config config,Clock * clock)122*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<VideoTrackInterface> CreateLocalVideoTrack(
123*d9f75844SAndroid Build Coastguard Worker       FrameGeneratorCapturerVideoTrackSource::Config config,
124*d9f75844SAndroid Build Coastguard Worker       Clock* clock) {
125*d9f75844SAndroid Build Coastguard Worker     video_track_sources_.emplace_back(
126*d9f75844SAndroid Build Coastguard Worker         rtc::make_ref_counted<FrameGeneratorCapturerVideoTrackSource>(
127*d9f75844SAndroid Build Coastguard Worker             config, clock, /*is_screencast=*/false));
128*d9f75844SAndroid Build Coastguard Worker     video_track_sources_.back()->Start();
129*d9f75844SAndroid Build Coastguard Worker     return rtc::scoped_refptr<VideoTrackInterface>(
130*d9f75844SAndroid Build Coastguard Worker         pc_factory()->CreateVideoTrack(rtc::CreateRandomUuid(),
131*d9f75844SAndroid Build Coastguard Worker                                        video_track_sources_.back().get()));
132*d9f75844SAndroid Build Coastguard Worker   }
133*d9f75844SAndroid Build Coastguard Worker 
CreateLocalAudioTrack(const cricket::AudioOptions options)134*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<AudioTrackInterface> CreateLocalAudioTrack(
135*d9f75844SAndroid Build Coastguard Worker       const cricket::AudioOptions options) {
136*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<AudioSourceInterface> source =
137*d9f75844SAndroid Build Coastguard Worker         pc_factory()->CreateAudioSource(options);
138*d9f75844SAndroid Build Coastguard Worker     return pc_factory()->CreateAudioTrack(rtc::CreateRandomUuid(),
139*d9f75844SAndroid Build Coastguard Worker                                           source.get());
140*d9f75844SAndroid Build Coastguard Worker   }
141*d9f75844SAndroid Build Coastguard Worker 
142*d9f75844SAndroid Build Coastguard Worker  private:
143*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::scoped_refptr<FrameGeneratorCapturerVideoTrackSource>>
144*d9f75844SAndroid Build Coastguard Worker       video_track_sources_;
145*d9f75844SAndroid Build Coastguard Worker };
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker // TODO(shampson): Paramaterize the test to run for both Plan B & Unified Plan.
148*d9f75844SAndroid Build Coastguard Worker class PeerConnectionRampUpTest : public ::testing::Test {
149*d9f75844SAndroid Build Coastguard Worker  public:
PeerConnectionRampUpTest()150*d9f75844SAndroid Build Coastguard Worker   PeerConnectionRampUpTest()
151*d9f75844SAndroid Build Coastguard Worker       : clock_(Clock::GetRealTimeClock()),
152*d9f75844SAndroid Build Coastguard Worker         virtual_socket_server_(new rtc::VirtualSocketServer()),
153*d9f75844SAndroid Build Coastguard Worker         firewall_socket_server_(
154*d9f75844SAndroid Build Coastguard Worker             new rtc::FirewallSocketServer(virtual_socket_server_.get())),
155*d9f75844SAndroid Build Coastguard Worker         network_thread_(new rtc::Thread(firewall_socket_server_.get())),
156*d9f75844SAndroid Build Coastguard Worker         worker_thread_(rtc::Thread::Create()) {
157*d9f75844SAndroid Build Coastguard Worker     network_thread_->SetName("PCNetworkThread", this);
158*d9f75844SAndroid Build Coastguard Worker     worker_thread_->SetName("PCWorkerThread", this);
159*d9f75844SAndroid Build Coastguard Worker     RTC_CHECK(network_thread_->Start());
160*d9f75844SAndroid Build Coastguard Worker     RTC_CHECK(worker_thread_->Start());
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker     virtual_socket_server_->set_bandwidth(kNetworkBandwidth / 8);
163*d9f75844SAndroid Build Coastguard Worker     pc_factory_ = CreatePeerConnectionFactory(
164*d9f75844SAndroid Build Coastguard Worker         network_thread_.get(), worker_thread_.get(), rtc::Thread::Current(),
165*d9f75844SAndroid Build Coastguard Worker         rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
166*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
167*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
168*d9f75844SAndroid Build Coastguard Worker         nullptr /* audio_mixer */, nullptr /* audio_processing */);
169*d9f75844SAndroid Build Coastguard Worker   }
170*d9f75844SAndroid Build Coastguard Worker 
~PeerConnectionRampUpTest()171*d9f75844SAndroid Build Coastguard Worker   virtual ~PeerConnectionRampUpTest() {
172*d9f75844SAndroid Build Coastguard Worker     SendTask(network_thread(), [this] { turn_servers_.clear(); });
173*d9f75844SAndroid Build Coastguard Worker   }
174*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionWrappers(const RTCConfiguration & caller_config,const RTCConfiguration & callee_config)175*d9f75844SAndroid Build Coastguard Worker   bool CreatePeerConnectionWrappers(const RTCConfiguration& caller_config,
176*d9f75844SAndroid Build Coastguard Worker                                     const RTCConfiguration& callee_config) {
177*d9f75844SAndroid Build Coastguard Worker     caller_ = CreatePeerConnectionWrapper(caller_config);
178*d9f75844SAndroid Build Coastguard Worker     callee_ = CreatePeerConnectionWrapper(callee_config);
179*d9f75844SAndroid Build Coastguard Worker     return caller_ && callee_;
180*d9f75844SAndroid Build Coastguard Worker   }
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapperForRampUpTest>
CreatePeerConnectionWrapper(const RTCConfiguration & config)183*d9f75844SAndroid Build Coastguard Worker   CreatePeerConnectionWrapper(const RTCConfiguration& config) {
184*d9f75844SAndroid Build Coastguard Worker     auto* fake_network_manager = new rtc::FakeNetworkManager();
185*d9f75844SAndroid Build Coastguard Worker     fake_network_manager->AddInterface(kDefaultLocalAddress);
186*d9f75844SAndroid Build Coastguard Worker     fake_network_managers_.emplace_back(fake_network_manager);
187*d9f75844SAndroid Build Coastguard Worker 
188*d9f75844SAndroid Build Coastguard Worker     auto observer = std::make_unique<MockPeerConnectionObserver>();
189*d9f75844SAndroid Build Coastguard Worker     webrtc::PeerConnectionDependencies dependencies(observer.get());
190*d9f75844SAndroid Build Coastguard Worker     cricket::BasicPortAllocator* port_allocator =
191*d9f75844SAndroid Build Coastguard Worker         new cricket::BasicPortAllocator(
192*d9f75844SAndroid Build Coastguard Worker             fake_network_manager,
193*d9f75844SAndroid Build Coastguard Worker             std::make_unique<rtc::BasicPacketSocketFactory>(
194*d9f75844SAndroid Build Coastguard Worker                 firewall_socket_server_.get()));
195*d9f75844SAndroid Build Coastguard Worker     port_allocator->set_step_delay(cricket::kDefaultStepDelay);
196*d9f75844SAndroid Build Coastguard Worker     dependencies.allocator =
197*d9f75844SAndroid Build Coastguard Worker         std::unique_ptr<cricket::BasicPortAllocator>(port_allocator);
198*d9f75844SAndroid Build Coastguard Worker     dependencies.tls_cert_verifier =
199*d9f75844SAndroid Build Coastguard Worker         std::make_unique<rtc::TestCertificateVerifier>();
200*d9f75844SAndroid Build Coastguard Worker 
201*d9f75844SAndroid Build Coastguard Worker     auto result = pc_factory_->CreatePeerConnectionOrError(
202*d9f75844SAndroid Build Coastguard Worker         config, std::move(dependencies));
203*d9f75844SAndroid Build Coastguard Worker     if (!result.ok()) {
204*d9f75844SAndroid Build Coastguard Worker       return nullptr;
205*d9f75844SAndroid Build Coastguard Worker     }
206*d9f75844SAndroid Build Coastguard Worker 
207*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<PeerConnectionWrapperForRampUpTest>(
208*d9f75844SAndroid Build Coastguard Worker         pc_factory_, result.MoveValue(), std::move(observer));
209*d9f75844SAndroid Build Coastguard Worker   }
210*d9f75844SAndroid Build Coastguard Worker 
SetupOneWayCall()211*d9f75844SAndroid Build Coastguard Worker   void SetupOneWayCall() {
212*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(caller_);
213*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(callee_);
214*d9f75844SAndroid Build Coastguard Worker     FrameGeneratorCapturerVideoTrackSource::Config config;
215*d9f75844SAndroid Build Coastguard Worker     caller_->AddTrack(caller_->CreateLocalVideoTrack(config, clock_));
216*d9f75844SAndroid Build Coastguard Worker     // Disable highpass filter so that we can get all the test audio frames.
217*d9f75844SAndroid Build Coastguard Worker     cricket::AudioOptions options;
218*d9f75844SAndroid Build Coastguard Worker     options.highpass_filter = false;
219*d9f75844SAndroid Build Coastguard Worker     caller_->AddTrack(caller_->CreateLocalAudioTrack(options));
220*d9f75844SAndroid Build Coastguard Worker 
221*d9f75844SAndroid Build Coastguard Worker     // Do the SDP negotiation, and also exchange ice candidates.
222*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(caller_->ExchangeOfferAnswerWith(callee_.get()));
223*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(
224*d9f75844SAndroid Build Coastguard Worker         caller_->signaling_state() == PeerConnectionInterface::kStable,
225*d9f75844SAndroid Build Coastguard Worker         kDefaultTimeoutMs);
226*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(caller_->IsIceGatheringDone(), kDefaultTimeoutMs);
227*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(callee_->IsIceGatheringDone(), kDefaultTimeoutMs);
228*d9f75844SAndroid Build Coastguard Worker 
229*d9f75844SAndroid Build Coastguard Worker     // Connect an ICE candidate pairs.
230*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(
231*d9f75844SAndroid Build Coastguard Worker         callee_->AddIceCandidates(caller_->observer()->GetAllCandidates()));
232*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(
233*d9f75844SAndroid Build Coastguard Worker         caller_->AddIceCandidates(callee_->observer()->GetAllCandidates()));
234*d9f75844SAndroid Build Coastguard Worker     // This means that ICE and DTLS are connected.
235*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(callee_->IsIceConnected(), kDefaultTimeoutMs);
236*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(caller_->IsIceConnected(), kDefaultTimeoutMs);
237*d9f75844SAndroid Build Coastguard Worker   }
238*d9f75844SAndroid Build Coastguard Worker 
CreateTurnServer(cricket::ProtocolType type,const std::string & common_name="test turn server")239*d9f75844SAndroid Build Coastguard Worker   void CreateTurnServer(cricket::ProtocolType type,
240*d9f75844SAndroid Build Coastguard Worker                         const std::string& common_name = "test turn server") {
241*d9f75844SAndroid Build Coastguard Worker     rtc::Thread* thread = network_thread();
242*d9f75844SAndroid Build Coastguard Worker     rtc::SocketFactory* factory = firewall_socket_server_.get();
243*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<cricket::TestTurnServer> turn_server;
244*d9f75844SAndroid Build Coastguard Worker     SendTask(network_thread_.get(), [&] {
245*d9f75844SAndroid Build Coastguard Worker       static const rtc::SocketAddress turn_server_internal_address{
246*d9f75844SAndroid Build Coastguard Worker           kTurnInternalAddress, kTurnInternalPort};
247*d9f75844SAndroid Build Coastguard Worker       static const rtc::SocketAddress turn_server_external_address{
248*d9f75844SAndroid Build Coastguard Worker           kTurnExternalAddress, kTurnExternalPort};
249*d9f75844SAndroid Build Coastguard Worker       turn_server = std::make_unique<cricket::TestTurnServer>(
250*d9f75844SAndroid Build Coastguard Worker           thread, factory, turn_server_internal_address,
251*d9f75844SAndroid Build Coastguard Worker           turn_server_external_address, type, true /*ignore_bad_certs=*/,
252*d9f75844SAndroid Build Coastguard Worker           common_name);
253*d9f75844SAndroid Build Coastguard Worker     });
254*d9f75844SAndroid Build Coastguard Worker     turn_servers_.push_back(std::move(turn_server));
255*d9f75844SAndroid Build Coastguard Worker   }
256*d9f75844SAndroid Build Coastguard Worker 
257*d9f75844SAndroid Build Coastguard Worker   // First runs the call for kRampUpTimeMs to ramp up the bandwidth estimate.
258*d9f75844SAndroid Build Coastguard Worker   // Then runs the test for the remaining test time, grabbing the bandwidth
259*d9f75844SAndroid Build Coastguard Worker   // estimation stat, every kPollIntervalTimeMs. When finished, averages the
260*d9f75844SAndroid Build Coastguard Worker   // bandwidth estimations and prints the bandwidth estimation result as a perf
261*d9f75844SAndroid Build Coastguard Worker   // metric.
RunTest(const std::string & test_string)262*d9f75844SAndroid Build Coastguard Worker   void RunTest(const std::string& test_string) {
263*d9f75844SAndroid Build Coastguard Worker     rtc::Thread::Current()->ProcessMessages(kRampUpTimeMs);
264*d9f75844SAndroid Build Coastguard Worker     int number_of_polls =
265*d9f75844SAndroid Build Coastguard Worker         (kDefaultTestTimeMs - kRampUpTimeMs) / kPollIntervalTimeMs;
266*d9f75844SAndroid Build Coastguard Worker     int total_bwe = 0;
267*d9f75844SAndroid Build Coastguard Worker     for (int i = 0; i < number_of_polls; ++i) {
268*d9f75844SAndroid Build Coastguard Worker       rtc::Thread::Current()->ProcessMessages(kPollIntervalTimeMs);
269*d9f75844SAndroid Build Coastguard Worker       total_bwe += static_cast<int>(GetCallerAvailableBitrateEstimate());
270*d9f75844SAndroid Build Coastguard Worker     }
271*d9f75844SAndroid Build Coastguard Worker     double average_bandwidth_estimate = total_bwe / number_of_polls;
272*d9f75844SAndroid Build Coastguard Worker     std::string value_description =
273*d9f75844SAndroid Build Coastguard Worker         "bwe_after_" + std::to_string(kDefaultTestTimeMs / 1000) + "_seconds";
274*d9f75844SAndroid Build Coastguard Worker     GetGlobalMetricsLogger()->LogSingleValueMetric(
275*d9f75844SAndroid Build Coastguard Worker         "peerconnection_ramp_up_" + test_string, value_description,
276*d9f75844SAndroid Build Coastguard Worker         average_bandwidth_estimate, Unit::kUnitless,
277*d9f75844SAndroid Build Coastguard Worker         ImprovementDirection::kNeitherIsBetter);
278*d9f75844SAndroid Build Coastguard Worker   }
279*d9f75844SAndroid Build Coastguard Worker 
network_thread()280*d9f75844SAndroid Build Coastguard Worker   rtc::Thread* network_thread() { return network_thread_.get(); }
281*d9f75844SAndroid Build Coastguard Worker 
firewall_socket_server()282*d9f75844SAndroid Build Coastguard Worker   rtc::FirewallSocketServer* firewall_socket_server() {
283*d9f75844SAndroid Build Coastguard Worker     return firewall_socket_server_.get();
284*d9f75844SAndroid Build Coastguard Worker   }
285*d9f75844SAndroid Build Coastguard Worker 
caller()286*d9f75844SAndroid Build Coastguard Worker   PeerConnectionWrapperForRampUpTest* caller() { return caller_.get(); }
287*d9f75844SAndroid Build Coastguard Worker 
callee()288*d9f75844SAndroid Build Coastguard Worker   PeerConnectionWrapperForRampUpTest* callee() { return callee_.get(); }
289*d9f75844SAndroid Build Coastguard Worker 
290*d9f75844SAndroid Build Coastguard Worker  private:
291*d9f75844SAndroid Build Coastguard Worker   // Gets the caller's outgoing available bitrate from the stats. Returns 0 if
292*d9f75844SAndroid Build Coastguard Worker   // something went wrong. It takes the outgoing bitrate from the current
293*d9f75844SAndroid Build Coastguard Worker   // selected ICE candidate pair's stats.
GetCallerAvailableBitrateEstimate()294*d9f75844SAndroid Build Coastguard Worker   double GetCallerAvailableBitrateEstimate() {
295*d9f75844SAndroid Build Coastguard Worker     auto stats = caller_->GetStats();
296*d9f75844SAndroid Build Coastguard Worker     auto transport_stats = stats->GetStatsOfType<RTCTransportStats>();
297*d9f75844SAndroid Build Coastguard Worker     if (transport_stats.size() == 0u ||
298*d9f75844SAndroid Build Coastguard Worker         !transport_stats[0]->selected_candidate_pair_id.is_defined()) {
299*d9f75844SAndroid Build Coastguard Worker       return 0;
300*d9f75844SAndroid Build Coastguard Worker     }
301*d9f75844SAndroid Build Coastguard Worker     std::string selected_ice_id =
302*d9f75844SAndroid Build Coastguard Worker         transport_stats[0]->selected_candidate_pair_id.ValueToString();
303*d9f75844SAndroid Build Coastguard Worker     // Use the selected ICE candidate pair ID to get the appropriate ICE stats.
304*d9f75844SAndroid Build Coastguard Worker     const RTCIceCandidatePairStats ice_candidate_pair_stats =
305*d9f75844SAndroid Build Coastguard Worker         stats->Get(selected_ice_id)->cast_to<const RTCIceCandidatePairStats>();
306*d9f75844SAndroid Build Coastguard Worker     if (ice_candidate_pair_stats.available_outgoing_bitrate.is_defined()) {
307*d9f75844SAndroid Build Coastguard Worker       return *ice_candidate_pair_stats.available_outgoing_bitrate;
308*d9f75844SAndroid Build Coastguard Worker     }
309*d9f75844SAndroid Build Coastguard Worker     // We couldn't get the `available_outgoing_bitrate` for the active candidate
310*d9f75844SAndroid Build Coastguard Worker     // pair.
311*d9f75844SAndroid Build Coastguard Worker     return 0;
312*d9f75844SAndroid Build Coastguard Worker   }
313*d9f75844SAndroid Build Coastguard Worker 
314*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
315*d9f75844SAndroid Build Coastguard Worker   // The turn servers should be accessed & deleted on the network thread to
316*d9f75844SAndroid Build Coastguard Worker   // avoid a race with the socket read/write which occurs on the network thread.
317*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<cricket::TestTurnServer>> turn_servers_;
318*d9f75844SAndroid Build Coastguard Worker   // `virtual_socket_server_` is used by `network_thread_` so it must be
319*d9f75844SAndroid Build Coastguard Worker   // destroyed later.
320*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/7668): We would like to update the virtual network we
321*d9f75844SAndroid Build Coastguard Worker   // use for this test. VirtualSocketServer isn't ideal because:
322*d9f75844SAndroid Build Coastguard Worker   // 1) It uses the same queue & network capacity for both directions.
323*d9f75844SAndroid Build Coastguard Worker   // 2) VirtualSocketServer implements how the network bandwidth affects the
324*d9f75844SAndroid Build Coastguard Worker   //    send delay differently than the SimulatedNetwork, used by the
325*d9f75844SAndroid Build Coastguard Worker   //    FakeNetworkPipe. It would be ideal if all of levels of virtual
326*d9f75844SAndroid Build Coastguard Worker   //    networks used in testing were consistent.
327*d9f75844SAndroid Build Coastguard Worker   // We would also like to update this test to record the time to ramp up,
328*d9f75844SAndroid Build Coastguard Worker   // down, and back up (similar to in rampup_tests.cc). This is problematic with
329*d9f75844SAndroid Build Coastguard Worker   // the VirtualSocketServer. The first ramp down time is very noisy and the
330*d9f75844SAndroid Build Coastguard Worker   // second ramp up time can take up to 300 seconds, most likely due to a built
331*d9f75844SAndroid Build Coastguard Worker   // up queue.
332*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::VirtualSocketServer> virtual_socket_server_;
333*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::FirewallSocketServer> firewall_socket_server_;
334*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> network_thread_;
335*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> worker_thread_;
336*d9f75844SAndroid Build Coastguard Worker   // The `pc_factory` uses `network_thread_` & `worker_thread_`, so it must be
337*d9f75844SAndroid Build Coastguard Worker   // destroyed first.
338*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_network_managers_;
339*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
340*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapperForRampUpTest> caller_;
341*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapperForRampUpTest> callee_;
342*d9f75844SAndroid Build Coastguard Worker };
343*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRampUpTest,Bwe_After_TurnOverTCP)344*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRampUpTest, Bwe_After_TurnOverTCP) {
345*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(cricket::ProtocolType::PROTO_TCP);
346*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::IceServer ice_server;
347*d9f75844SAndroid Build Coastguard Worker   std::string ice_server_url = "turn:" + std::string(kTurnInternalAddress) +
348*d9f75844SAndroid Build Coastguard Worker                                ":" + std::to_string(kTurnInternalPort) +
349*d9f75844SAndroid Build Coastguard Worker                                "?transport=tcp";
350*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back(ice_server_url);
351*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
352*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
353*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
354*d9f75844SAndroid Build Coastguard Worker   client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
355*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server);
356*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = PeerConnectionInterface::kRelay;
357*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
358*d9f75844SAndroid Build Coastguard Worker   client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
359*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server);
360*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = PeerConnectionInterface::kRelay;
361*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
362*d9f75844SAndroid Build Coastguard Worker 
363*d9f75844SAndroid Build Coastguard Worker   SetupOneWayCall();
364*d9f75844SAndroid Build Coastguard Worker   RunTest("turn_over_tcp");
365*d9f75844SAndroid Build Coastguard Worker }
366*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRampUpTest,Bwe_After_TurnOverUDP)367*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRampUpTest, Bwe_After_TurnOverUDP) {
368*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(cricket::ProtocolType::PROTO_UDP);
369*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::IceServer ice_server;
370*d9f75844SAndroid Build Coastguard Worker   std::string ice_server_url = "turn:" + std::string(kTurnInternalAddress) +
371*d9f75844SAndroid Build Coastguard Worker                                ":" + std::to_string(kTurnInternalPort);
372*d9f75844SAndroid Build Coastguard Worker 
373*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back(ice_server_url);
374*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
375*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
376*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
377*d9f75844SAndroid Build Coastguard Worker   client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
378*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server);
379*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = PeerConnectionInterface::kRelay;
380*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
381*d9f75844SAndroid Build Coastguard Worker   client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
382*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server);
383*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = PeerConnectionInterface::kRelay;
384*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker   SetupOneWayCall();
387*d9f75844SAndroid Build Coastguard Worker   RunTest("turn_over_udp");
388*d9f75844SAndroid Build Coastguard Worker }
389*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRampUpTest,Bwe_After_TurnOverTLS)390*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRampUpTest, Bwe_After_TurnOverTLS) {
391*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(cricket::ProtocolType::PROTO_TLS, kTurnInternalAddress);
392*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::IceServer ice_server;
393*d9f75844SAndroid Build Coastguard Worker   std::string ice_server_url = "turns:" + std::string(kTurnInternalAddress) +
394*d9f75844SAndroid Build Coastguard Worker                                ":" + std::to_string(kTurnInternalPort) +
395*d9f75844SAndroid Build Coastguard Worker                                "?transport=tcp";
396*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back(ice_server_url);
397*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
398*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
399*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
400*d9f75844SAndroid Build Coastguard Worker   client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
401*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server);
402*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = PeerConnectionInterface::kRelay;
403*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
404*d9f75844SAndroid Build Coastguard Worker   client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
405*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server);
406*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = PeerConnectionInterface::kRelay;
407*d9f75844SAndroid Build Coastguard Worker 
408*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
409*d9f75844SAndroid Build Coastguard Worker 
410*d9f75844SAndroid Build Coastguard Worker   SetupOneWayCall();
411*d9f75844SAndroid Build Coastguard Worker   RunTest("turn_over_tls");
412*d9f75844SAndroid Build Coastguard Worker }
413*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRampUpTest,Bwe_After_UDPPeerToPeer)414*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRampUpTest, Bwe_After_UDPPeerToPeer) {
415*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
416*d9f75844SAndroid Build Coastguard Worker   client_1_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
417*d9f75844SAndroid Build Coastguard Worker   client_1_config.tcp_candidate_policy =
418*d9f75844SAndroid Build Coastguard Worker       PeerConnection::kTcpCandidatePolicyDisabled;
419*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
420*d9f75844SAndroid Build Coastguard Worker   client_2_config.sdp_semantics = SdpSemantics::kUnifiedPlan;
421*d9f75844SAndroid Build Coastguard Worker   client_2_config.tcp_candidate_policy =
422*d9f75844SAndroid Build Coastguard Worker       PeerConnection::kTcpCandidatePolicyDisabled;
423*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers(client_1_config, client_2_config));
424*d9f75844SAndroid Build Coastguard Worker 
425*d9f75844SAndroid Build Coastguard Worker   SetupOneWayCall();
426*d9f75844SAndroid Build Coastguard Worker   RunTest("udp_peer_to_peer");
427*d9f75844SAndroid Build Coastguard Worker }
428*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionRampUpTest,Bwe_After_TCPPeerToPeer)429*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionRampUpTest, Bwe_After_TCPPeerToPeer) {
430*d9f75844SAndroid Build Coastguard Worker   firewall_socket_server()->set_udp_sockets_enabled(false);
431*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
432*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
433*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers(config, config));
434*d9f75844SAndroid Build Coastguard Worker 
435*d9f75844SAndroid Build Coastguard Worker   SetupOneWayCall();
436*d9f75844SAndroid Build Coastguard Worker   RunTest("tcp_peer_to_peer");
437*d9f75844SAndroid Build Coastguard Worker }
438*d9f75844SAndroid Build Coastguard Worker 
439*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
440