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:
Artem Titov
2019-03-20 11:18:58 +01:00
committed by Commit Bot
parent 0b44314b76
commit d09bc55d3b
4 changed files with 226 additions and 56 deletions

View File

@ -27,6 +27,7 @@
#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"
#include "logging/rtc_event_log/rtc_event_log_factory_interface.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/network.h"
#include "rtc_base/rtc_certificate_generator.h" #include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_certificate.h" #include "rtc_base/ssl_certificate.h"
@ -199,6 +200,55 @@ class PeerConnectionE2EQualityTestFixture {
PeerConnectionInterface::RTCConfiguration rtc_configuration; 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 // Contains parameters, that describe how long framework should run quality
// test. // test.
struct RunParams { struct RunParams {
@ -208,6 +258,8 @@ class PeerConnectionE2EQualityTestFixture {
TimeDelta run_duration; TimeDelta run_duration;
}; };
virtual ~PeerConnectionE2EQualityTestFixture() = default;
// Add activity that will be executed on the best effort at least after // 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 // |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 // exchange, ICE gathering will be done and ICE candidates will passed to
@ -222,12 +274,16 @@ class PeerConnectionE2EQualityTestFixture {
TimeDelta interval, TimeDelta interval,
std::function<void(TimeDelta)> func) = 0; std::function<void(TimeDelta)> func) = 0;
virtual void Run(std::unique_ptr<InjectableComponents> alice_components, // Add a new peer to the call and return an object through which caller
std::unique_ptr<Params> alice_params, // can configure peer's behavior.
std::unique_ptr<InjectableComponents> bob_components, // |network_thread| will be used as network thread for peer's peer connection
std::unique_ptr<Params> bob_params, // |network_manager| will be used to provide network interfaces for peer's
RunParams run_params) = 0; // peer connection.
virtual ~PeerConnectionE2EQualityTestFixture() = default; // |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 } // namespace webrtc_pc_e2e

View File

@ -39,26 +39,10 @@ void PrintFrameCounters(const std::string& name,
} // namespace } // namespace
TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) { TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
using Params = PeerConnectionE2EQualityTestFixture::Params; using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
using RunParams = PeerConnectionE2EQualityTestFixture::RunParams; using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig; using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
using AudioConfig = PeerConnectionE2EQualityTestFixture::AudioConfig; 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 // Setup emulated network
std::unique_ptr<NetworkEmulationManager> network_emulation_manager = std::unique_ptr<NetworkEmulationManager> network_emulation_manager =
@ -81,22 +65,6 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
network_emulation_manager->CreateRoute(bob_endpoint, {bob_node}, network_emulation_manager->CreateRoute(bob_endpoint, {bob_node},
alice_endpoint); 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. // Create analyzers.
std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer = std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer =
absl::make_unique<DefaultVideoQualityAnalyzer>(); absl::make_unique<DefaultVideoQualityAnalyzer>();
@ -117,9 +85,30 @@ TEST(PeerConnectionE2EQualityTestSmokeTest, RunWithEmulatedNetwork) {
config.loss_percent = 5; config.loss_percent = 5;
alice_network_behavior_ptr->SetConfig(config); alice_network_behavior_ptr->SetConfig(config);
}); });
fixture->Run(std::move(alice_components), std::move(alice_params),
std::move(bob_components), std::move(bob_params), // Setup components. We need to provide rtc::NetworkManager compatible with
RunParams{TimeDelta::seconds(5)}); // 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()); PrintFrameCounters("Global", video_analyzer_ptr->GetGlobalCounters());
for (auto stream_label : video_analyzer_ptr->GetKnownVideoStreams()) { for (auto stream_label : video_analyzer_ptr->GetKnownVideoStreams()) {

View File

@ -195,16 +195,28 @@ void PeerConnectionE2EQualityTest::PostTask(ScheduledActivity activity) {
remaining_delay.ms()); 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( 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) { RunParams run_params) {
RTC_CHECK(alice_components); RTC_CHECK_EQ(peer_configurations_.size(), 2)
RTC_CHECK(alice_params); << "Only peer to peer calls are allowed, please add 2 peers";
RTC_CHECK(bob_components);
RTC_CHECK(bob_params); 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()}); SetDefaultValuesForMissingParams({alice_params.get(), bob_params.get()});
ValidateParams({alice_params.get(), bob_params.get()}); ValidateParams({alice_params.get(), bob_params.get()});

View File

@ -15,6 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "absl/memory/memory.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "api/units/timestamp.h" #include "api/units/timestamp.h"
#include "pc/test/frame_generator_capturer_video_track_source.h" #include "pc/test/frame_generator_capturer_video_track_source.h"
@ -33,6 +34,116 @@
namespace webrtc { namespace webrtc {
namespace webrtc_pc_e2e { 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 class PeerConnectionE2EQualityTest
: public PeerConnectionE2EQualityTestFixture { : public PeerConnectionE2EQualityTestFixture {
public: public:
@ -43,6 +154,7 @@ class PeerConnectionE2EQualityTest
PeerConnectionE2EQualityTestFixture::VideoGeneratorType; PeerConnectionE2EQualityTestFixture::VideoGeneratorType;
using RunParams = PeerConnectionE2EQualityTestFixture::RunParams; using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig; using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
PeerConnectionE2EQualityTest( PeerConnectionE2EQualityTest(
std::string test_case_name, std::string test_case_name,
@ -51,18 +163,17 @@ class PeerConnectionE2EQualityTest
~PeerConnectionE2EQualityTest() override = default; ~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, void ExecuteAt(TimeDelta target_time_since_start,
std::function<void(TimeDelta)> func) override; std::function<void(TimeDelta)> func) override;
void ExecuteEvery(TimeDelta initial_delay_since_start, void ExecuteEvery(TimeDelta initial_delay_since_start,
TimeDelta interval, TimeDelta interval,
std::function<void(TimeDelta)> func) override; 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: private:
struct ScheduledActivity { struct ScheduledActivity {
ScheduledActivity(TimeDelta initial_delay_since_start, ScheduledActivity(TimeDelta initial_delay_since_start,
@ -116,6 +227,8 @@ class PeerConnectionE2EQualityTest
encoded_image_id_controller_; encoded_image_id_controller_;
std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer_; std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer_;
std::vector<std::unique_ptr<PeerConfigurerImpl>> peer_configurations_;
std::unique_ptr<TestPeer> alice_; std::unique_ptr<TestPeer> alice_;
std::unique_ptr<TestPeer> bob_; std::unique_ptr<TestPeer> bob_;