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