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}
diff --git a/test/pc/e2e/api/peerconnection_quality_test_fixture.h b/test/pc/e2e/api/peerconnection_quality_test_fixture.h
index e09b934..8638151 100644
--- a/test/pc/e2e/api/peerconnection_quality_test_fixture.h
+++ b/test/pc/e2e/api/peerconnection_quality_test_fixture.h
@@ -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 @@
     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 @@
     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 @@
                             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
diff --git a/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
index 04d5b6c..9965257 100644
--- a/test/pc/e2e/peer_connection_e2e_smoke_test.cc
+++ b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
@@ -39,26 +39,10 @@
 }  // 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 @@
   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 @@
                        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()) {
diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc
index 91df376..115d37f 100644
--- a/test/pc/e2e/peer_connection_quality_test.cc
+++ b/test/pc/e2e/peer_connection_quality_test.cc
@@ -195,16 +195,28 @@
       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()});
diff --git a/test/pc/e2e/peer_connection_quality_test.h b/test/pc/e2e/peer_connection_quality_test.h
index 8da8464..ea20fa2 100644
--- a/test/pc/e2e/peer_connection_quality_test.h
+++ b/test/pc/e2e/peer_connection_quality_test.h
@@ -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 @@
       PeerConnectionE2EQualityTestFixture::VideoGeneratorType;
   using RunParams = PeerConnectionE2EQualityTestFixture::RunParams;
   using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig;
+  using PeerConfigurer = PeerConnectionE2EQualityTestFixture::PeerConfigurer;
 
   PeerConnectionE2EQualityTest(
       std::string test_case_name,
@@ -51,18 +163,17 @@
 
   ~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 @@
       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_;