Introduce new API for runnig PC e2e test fixture
Bug: webrtc:10138 Change-Id: I704f09843e5b8a05de4a1d25a4baa44c683a5552 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/128402 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Peter Slatala <psla@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27204}
This commit is contained in:
@ -27,6 +27,7 @@
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log_factory_interface.h"
|
||||
#include "rtc_base/function_view.h"
|
||||
#include "rtc_base/network.h"
|
||||
#include "rtc_base/rtc_certificate_generator.h"
|
||||
#include "rtc_base/ssl_certificate.h"
|
||||
@ -199,6 +200,55 @@ class PeerConnectionE2EQualityTestFixture {
|
||||
PeerConnectionInterface::RTCConfiguration rtc_configuration;
|
||||
};
|
||||
|
||||
// This class is used to fully configure one peer inside the call.
|
||||
class PeerConfigurer {
|
||||
public:
|
||||
virtual ~PeerConfigurer() = default;
|
||||
|
||||
// The parameters of the following 7 methods will be passed to the
|
||||
// PeerConnectionFactoryInterface implementation that will be created for
|
||||
// this peer.
|
||||
virtual PeerConfigurer* SetCallFactory(
|
||||
std::unique_ptr<CallFactoryInterface> call_factory) = 0;
|
||||
virtual PeerConfigurer* SetEventLogFactory(
|
||||
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) = 0;
|
||||
virtual PeerConfigurer* SetFecControllerFactory(
|
||||
std::unique_ptr<FecControllerFactoryInterface>
|
||||
fec_controller_factory) = 0;
|
||||
virtual PeerConfigurer* SetNetworkControllerFactory(
|
||||
std::unique_ptr<NetworkControllerFactoryInterface>
|
||||
network_controller_factory) = 0;
|
||||
virtual PeerConfigurer* SetMediaTransportFactory(
|
||||
std::unique_ptr<MediaTransportFactory> media_transport_factory) = 0;
|
||||
virtual PeerConfigurer* SetVideoEncoderFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory) = 0;
|
||||
virtual PeerConfigurer* SetVideoDecoderFactory(
|
||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory) = 0;
|
||||
|
||||
// The parameters of the following 3 methods will be passed to the
|
||||
// PeerConnectionInterface implementation that will be created for this
|
||||
// peer.
|
||||
virtual PeerConfigurer* SetAsyncResolverFactory(
|
||||
std::unique_ptr<webrtc::AsyncResolverFactory>
|
||||
async_resolver_factory) = 0;
|
||||
virtual PeerConfigurer* SetRTCCertificateGenerator(
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface>
|
||||
cert_generator) = 0;
|
||||
virtual PeerConfigurer* SetSSLCertificateVerifier(
|
||||
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) = 0;
|
||||
|
||||
// Add new video stream to the call that will be sent from this peer.
|
||||
virtual PeerConfigurer* AddVideoConfig(VideoConfig config) = 0;
|
||||
// Set the audio stream for the call from this peer. If this method won't
|
||||
// be invoked, this peer will send no audio.
|
||||
virtual PeerConfigurer* SetAudioConfig(AudioConfig config) = 0;
|
||||
// If is set, an RTCEventLog will be saved in that location and it will be
|
||||
// available for further analysis.
|
||||
virtual PeerConfigurer* SetRtcEventLogPath(std::string path) = 0;
|
||||
virtual PeerConfigurer* SetRTCConfiguration(
|
||||
PeerConnectionInterface::RTCConfiguration configuration) = 0;
|
||||
};
|
||||
|
||||
// Contains parameters, that describe how long framework should run quality
|
||||
// test.
|
||||
struct RunParams {
|
||||
@ -208,6 +258,8 @@ class PeerConnectionE2EQualityTestFixture {
|
||||
TimeDelta run_duration;
|
||||
};
|
||||
|
||||
virtual ~PeerConnectionE2EQualityTestFixture() = default;
|
||||
|
||||
// Add activity that will be executed on the best effort at least after
|
||||
// |target_time_since_start| after call will be set up (after offer/answer
|
||||
// exchange, ICE gathering will be done and ICE candidates will passed to
|
||||
@ -222,12 +274,16 @@ class PeerConnectionE2EQualityTestFixture {
|
||||
TimeDelta interval,
|
||||
std::function<void(TimeDelta)> func) = 0;
|
||||
|
||||
virtual void Run(std::unique_ptr<InjectableComponents> alice_components,
|
||||
std::unique_ptr<Params> alice_params,
|
||||
std::unique_ptr<InjectableComponents> bob_components,
|
||||
std::unique_ptr<Params> bob_params,
|
||||
RunParams run_params) = 0;
|
||||
virtual ~PeerConnectionE2EQualityTestFixture() = default;
|
||||
// Add a new peer to the call and return an object through which caller
|
||||
// can configure peer's behavior.
|
||||
// |network_thread| will be used as network thread for peer's peer connection
|
||||
// |network_manager| will be used to provide network interfaces for peer's
|
||||
// peer connection.
|
||||
// |configurer| function will be used to configure peer in the call.
|
||||
virtual void AddPeer(rtc::Thread* network_thread,
|
||||
rtc::NetworkManager* network_manager,
|
||||
rtc::FunctionView<void(PeerConfigurer*)> configurer) = 0;
|
||||
virtual void Run(RunParams run_params) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc_pc_e2e
|
||||
|
@ -39,26 +39,10 @@ void PrintFrameCounters(const std::string& name,
|
||||
} // namespace
|
||||
|
||||
TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
|
||||
using Params = PeerConnectionE2EQualityTestFixture::Params;
|
||||
using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
|
||||
using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
|
||||
using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
|
||||
using AudioConfig = PeerConnectionE2EQualityTestFixture::AudioConfig;
|
||||
using InjectableComponents =
|
||||
PeerConnectionE2EQualityTestFixture::InjectableComponents;
|
||||
|
||||
auto alice_params = absl::make_unique<Params>();
|
||||
VideoConfig alice_video_config(640, 360, 30);
|
||||
alice_video_config.stream_label = "alice-video";
|
||||
|
||||
alice_params->video_configs.push_back(alice_video_config);
|
||||
alice_params->audio_config = AudioConfig();
|
||||
|
||||
auto bob_params = absl::make_unique<Params>();
|
||||
VideoConfig bob_video_config(640, 360, 30);
|
||||
bob_video_config.stream_label = "bob-video";
|
||||
|
||||
bob_params->video_configs.push_back(bob_video_config);
|
||||
bob_params->audio_config = AudioConfig();
|
||||
|
||||
// Setup emulated network
|
||||
std::unique_ptr<NetworkEmulationManager> network_emulation_manager =
|
||||
@ -81,22 +65,6 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
|
||||
network_emulation_manager->CreateRoute(bob_endpoint, {bob_node},
|
||||
alice_endpoint);
|
||||
|
||||
rtc::Thread* alice_network_thread =
|
||||
network_emulation_manager->CreateNetworkThread({alice_endpoint});
|
||||
rtc::Thread* bob_network_thread =
|
||||
network_emulation_manager->CreateNetworkThread({bob_endpoint});
|
||||
|
||||
// Setup components. We need to provide rtc::NetworkManager compatible with
|
||||
// emulated network layer.
|
||||
rtc::NetworkManager* alice_network_manager =
|
||||
network_emulation_manager->CreateNetworkManager({alice_endpoint});
|
||||
auto alice_components = absl::make_unique<InjectableComponents>(
|
||||
alice_network_thread, alice_network_manager);
|
||||
rtc::NetworkManager* bob_network_manager =
|
||||
network_emulation_manager->CreateNetworkManager({bob_endpoint});
|
||||
auto bob_components = absl::make_unique<InjectableComponents>(
|
||||
bob_network_thread, bob_network_manager);
|
||||
|
||||
// Create analyzers.
|
||||
std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer =
|
||||
absl::make_unique<DefaultVideoQualityAnalyzer>();
|
||||
@ -117,9 +85,30 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
|
||||
config.loss_percent = 5;
|
||||
alice_network_behavior_ptr->SetConfig(config);
|
||||
});
|
||||
fixture->Run(std::move(alice_components), std::move(alice_params),
|
||||
std::move(bob_components), std::move(bob_params),
|
||||
RunParams{TimeDelta::seconds(5)});
|
||||
|
||||
// Setup components. We need to provide rtc::NetworkManager compatible with
|
||||
// emulated network layer.
|
||||
fixture->AddPeer(
|
||||
network_emulation_manager->CreateNetworkThread({alice_endpoint}),
|
||||
network_emulation_manager->CreateNetworkManager({alice_endpoint}),
|
||||
[](PeerConfigurer* alice) {
|
||||
VideoConfig alice_video_config(640, 360, 30);
|
||||
alice_video_config.stream_label = "alice-video";
|
||||
alice->AddVideoConfig(std::move(alice_video_config));
|
||||
alice->SetAudioConfig(AudioConfig());
|
||||
});
|
||||
|
||||
fixture->AddPeer(
|
||||
network_emulation_manager->CreateNetworkThread({bob_endpoint}),
|
||||
network_emulation_manager->CreateNetworkManager({bob_endpoint}),
|
||||
[](PeerConfigurer* bob) {
|
||||
VideoConfig bob_video_config(640, 360, 30);
|
||||
bob_video_config.stream_label = "bob-video";
|
||||
bob->AddVideoConfig(std::move(bob_video_config));
|
||||
bob->SetAudioConfig(AudioConfig());
|
||||
});
|
||||
|
||||
fixture->Run(RunParams{TimeDelta::seconds(5)});
|
||||
|
||||
PrintFrameCounters("Global", video_analyzer_ptr->GetGlobalCounters());
|
||||
for (auto stream_label : video_analyzer_ptr->GetKnownVideoStreams()) {
|
||||
|
@ -195,16 +195,28 @@ void PeerConnectionE2EQualityTest::PostTask(ScheduledActivity activity) {
|
||||
remaining_delay.ms());
|
||||
}
|
||||
|
||||
void PeerConnectionE2EQualityTest::AddPeer(
|
||||
rtc::Thread* network_thread,
|
||||
rtc::NetworkManager* network_manager,
|
||||
rtc::FunctionView<void(PeerConfigurer*)> configurer) {
|
||||
peer_configurations_.push_back(
|
||||
absl::make_unique<PeerConfigurerImpl>(network_thread, network_manager));
|
||||
configurer(peer_configurations_.back().get());
|
||||
}
|
||||
|
||||
void PeerConnectionE2EQualityTest::Run(
|
||||
std::unique_ptr<InjectableComponents> alice_components,
|
||||
std::unique_ptr<Params> alice_params,
|
||||
std::unique_ptr<InjectableComponents> bob_components,
|
||||
std::unique_ptr<Params> bob_params,
|
||||
RunParams run_params) {
|
||||
RTC_CHECK(alice_components);
|
||||
RTC_CHECK(alice_params);
|
||||
RTC_CHECK(bob_components);
|
||||
RTC_CHECK(bob_params);
|
||||
RTC_CHECK_EQ(peer_configurations_.size(), 2)
|
||||
<< "Only peer to peer calls are allowed, please add 2 peers";
|
||||
|
||||
std::unique_ptr<Params> alice_params =
|
||||
peer_configurations_[0]->ReleaseParams();
|
||||
std::unique_ptr<InjectableComponents> alice_components =
|
||||
peer_configurations_[0]->ReleaseComponents();
|
||||
std::unique_ptr<Params> bob_params = peer_configurations_[1]->ReleaseParams();
|
||||
std::unique_ptr<InjectableComponents> bob_components =
|
||||
peer_configurations_[1]->ReleaseComponents();
|
||||
peer_configurations_.clear();
|
||||
|
||||
SetDefaultValuesForMissingParams({alice_params.get(), bob_params.get()});
|
||||
ValidateParams({alice_params.get(), bob_params.get()});
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "pc/test/frame_generator_capturer_video_track_source.h"
|
||||
@ -33,6 +34,116 @@
|
||||
namespace webrtc {
|
||||
namespace webrtc_pc_e2e {
|
||||
|
||||
class PeerConfigurerImpl final
|
||||
: public PeerConnectionE2EQualityTestFixture::PeerConfigurer {
|
||||
public:
|
||||
using Params = PeerConnectionE2EQualityTestFixture::Params;
|
||||
using InjectableComponents =
|
||||
PeerConnectionE2EQualityTestFixture::InjectableComponents;
|
||||
|
||||
PeerConfigurerImpl(rtc::Thread* network_thread,
|
||||
rtc::NetworkManager* network_manager)
|
||||
: components_(absl::make_unique<InjectableComponents>(network_thread,
|
||||
network_manager)),
|
||||
params_(absl::make_unique<Params>()) {}
|
||||
|
||||
PeerConfigurer* SetCallFactory(
|
||||
std::unique_ptr<CallFactoryInterface> call_factory) override {
|
||||
components_->pcf_dependencies->call_factory = std::move(call_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetEventLogFactory(
|
||||
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) override {
|
||||
components_->pcf_dependencies->event_log_factory =
|
||||
std::move(event_log_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetFecControllerFactory(
|
||||
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory)
|
||||
override {
|
||||
components_->pcf_dependencies->fec_controller_factory =
|
||||
std::move(fec_controller_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetNetworkControllerFactory(
|
||||
std::unique_ptr<NetworkControllerFactoryInterface>
|
||||
network_controller_factory) override {
|
||||
components_->pcf_dependencies->network_controller_factory =
|
||||
std::move(network_controller_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetMediaTransportFactory(
|
||||
std::unique_ptr<MediaTransportFactory> media_transport_factory) override {
|
||||
components_->pcf_dependencies->media_transport_factory =
|
||||
std::move(media_transport_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetVideoEncoderFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory) override {
|
||||
components_->pcf_dependencies->video_encoder_factory =
|
||||
std::move(video_encoder_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetVideoDecoderFactory(
|
||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory) override {
|
||||
components_->pcf_dependencies->video_decoder_factory =
|
||||
std::move(video_decoder_factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
PeerConfigurer* SetAsyncResolverFactory(
|
||||
std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory)
|
||||
override {
|
||||
components_->pc_dependencies->async_resolver_factory =
|
||||
std::move(async_resolver_factory);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetRTCCertificateGenerator(
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator)
|
||||
override {
|
||||
components_->pc_dependencies->cert_generator = std::move(cert_generator);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetSSLCertificateVerifier(
|
||||
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) override {
|
||||
components_->pc_dependencies->tls_cert_verifier =
|
||||
std::move(tls_cert_verifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
PeerConfigurer* AddVideoConfig(
|
||||
PeerConnectionE2EQualityTestFixture::VideoConfig config) override {
|
||||
params_->video_configs.push_back(std::move(config));
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetAudioConfig(
|
||||
PeerConnectionE2EQualityTestFixture::AudioConfig config) override {
|
||||
params_->audio_config = std::move(config);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetRtcEventLogPath(std::string path) override {
|
||||
params_->rtc_event_log_path = std::move(path);
|
||||
return this;
|
||||
}
|
||||
PeerConfigurer* SetRTCConfiguration(
|
||||
PeerConnectionInterface::RTCConfiguration configuration) override {
|
||||
params_->rtc_configuration = std::move(configuration);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class PeerConnectionE2EQualityTest;
|
||||
|
||||
std::unique_ptr<InjectableComponents> ReleaseComponents() {
|
||||
return std::move(components_);
|
||||
}
|
||||
std::unique_ptr<Params> ReleaseParams() { return std::move(params_); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<InjectableComponents> components_;
|
||||
std::unique_ptr<Params> params_;
|
||||
};
|
||||
|
||||
class PeerConnectionE2EQualityTest
|
||||
: public PeerConnectionE2EQualityTestFixture {
|
||||
public:
|
||||
@ -43,6 +154,7 @@ class PeerConnectionE2EQualityTest
|
||||
PeerConnectionE2EQualityTestFixture::VideoGeneratorType;
|
||||
using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
|
||||
using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
|
||||
using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
|
||||
|
||||
PeerConnectionE2EQualityTest(
|
||||
std::string test_case_name,
|
||||
@ -51,18 +163,17 @@ class PeerConnectionE2EQualityTest
|
||||
|
||||
~PeerConnectionE2EQualityTest() override = default;
|
||||
|
||||
void Run(std::unique_ptr<InjectableComponents> alice_components,
|
||||
std::unique_ptr<Params> alice_params,
|
||||
std::unique_ptr<InjectableComponents> bob_components,
|
||||
std::unique_ptr<Params> bob_params,
|
||||
RunParams run_params) override;
|
||||
|
||||
void ExecuteAt(TimeDelta target_time_since_start,
|
||||
std::function<void(TimeDelta)> func) override;
|
||||
void ExecuteEvery(TimeDelta initial_delay_since_start,
|
||||
TimeDelta interval,
|
||||
std::function<void(TimeDelta)> func) override;
|
||||
|
||||
void AddPeer(rtc::Thread* network_thread,
|
||||
rtc::NetworkManager* network_manager,
|
||||
rtc::FunctionView<void(PeerConfigurer*)> configurer) override;
|
||||
void Run(RunParams run_params) override;
|
||||
|
||||
private:
|
||||
struct ScheduledActivity {
|
||||
ScheduledActivity(TimeDelta initial_delay_since_start,
|
||||
@ -116,6 +227,8 @@ class PeerConnectionE2EQualityTest
|
||||
encoded_image_id_controller_;
|
||||
std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer_;
|
||||
|
||||
std::vector<std::unique_ptr<PeerConfigurerImpl>> peer_configurations_;
|
||||
|
||||
std::unique_ptr<TestPeer> alice_;
|
||||
std::unique_ptr<TestPeer> bob_;
|
||||
|
||||
|
Reference in New Issue
Block a user