|  | /* | 
|  | *  Copyright 2018 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  | #ifndef TEST_SCENARIO_SCENARIO_H_ | 
|  | #define TEST_SCENARIO_SCENARIO_H_ | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "absl/functional/any_invocable.h" | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "api/task_queue/task_queue_base.h" | 
|  | #include "api/test/time_controller.h" | 
|  | #include "rtc_base/fake_clock.h" | 
|  | #include "rtc_base/task_utils/repeating_task.h" | 
|  | #include "test/gtest.h" | 
|  | #include "test/logging/log_writer.h" | 
|  | #include "test/network/network_emulation_manager.h" | 
|  | #include "test/scenario/audio_stream.h" | 
|  | #include "test/scenario/call_client.h" | 
|  | #include "test/scenario/column_printer.h" | 
|  | #include "test/scenario/network_node.h" | 
|  | #include "test/scenario/scenario_config.h" | 
|  | #include "test/scenario/video_stream.h" | 
|  |  | 
|  | namespace webrtc { | 
|  | namespace test { | 
|  | // Scenario is a class owning everything for a test scenario. It creates and | 
|  | // holds network nodes, call clients and media streams. It also provides methods | 
|  | // for changing behavior at runtime. Since it always keeps ownership of the | 
|  | // created components, it generally returns non-owning pointers. It maintains | 
|  | // the life of its objects until it is destroyed. | 
|  | // For methods accepting configuration structs, a modifier function interface is | 
|  | // generally provided. This allows simple partial overriding of the default | 
|  | // configuration. | 
|  | class Scenario { | 
|  | public: | 
|  | Scenario(); | 
|  | explicit Scenario(const testing::TestInfo* test_info); | 
|  | explicit Scenario(absl::string_view file_name); | 
|  | Scenario(absl::string_view file_name, bool real_time); | 
|  | Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager, | 
|  | bool real_time); | 
|  |  | 
|  | ~Scenario(); | 
|  |  | 
|  | Scenario(const Scenario&) = delete; | 
|  | Scenario& operator=(const Scenario&) = delete; | 
|  |  | 
|  | NetworkEmulationManagerImpl* net() { return &network_manager_; } | 
|  |  | 
|  | EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config); | 
|  | EmulatedNetworkNode* CreateSimulationNode( | 
|  | std::function<void(NetworkSimulationConfig*)> config_modifier); | 
|  |  | 
|  | SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config); | 
|  | SimulationNode* CreateMutableSimulationNode( | 
|  | std::function<void(NetworkSimulationConfig*)> config_modifier); | 
|  |  | 
|  | CallClient* CreateClient(absl::string_view name, CallClientConfig config); | 
|  | CallClient* CreateClient( | 
|  | absl::string_view name, | 
|  | std::function<void(CallClientConfig*)> config_modifier); | 
|  |  | 
|  | CallClientPair* CreateRoutes(CallClient* first, | 
|  | std::vector<EmulatedNetworkNode*> send_link, | 
|  | CallClient* second, | 
|  | std::vector<EmulatedNetworkNode*> return_link); | 
|  |  | 
|  | CallClientPair* CreateRoutes(CallClient* first, | 
|  | std::vector<EmulatedNetworkNode*> send_link, | 
|  | DataSize first_overhead, | 
|  | CallClient* second, | 
|  | std::vector<EmulatedNetworkNode*> return_link, | 
|  | DataSize second_overhead); | 
|  |  | 
|  | void ChangeRoute(std::pair<CallClient*, CallClient*> clients, | 
|  | std::vector<EmulatedNetworkNode*> over_nodes); | 
|  |  | 
|  | void ChangeRoute(std::pair<CallClient*, CallClient*> clients, | 
|  | std::vector<EmulatedNetworkNode*> over_nodes, | 
|  | DataSize overhead); | 
|  |  | 
|  | VideoStreamPair* CreateVideoStream( | 
|  | std::pair<CallClient*, CallClient*> clients, | 
|  | std::function<void(VideoStreamConfig*)> config_modifier); | 
|  | VideoStreamPair* CreateVideoStream( | 
|  | std::pair<CallClient*, CallClient*> clients, | 
|  | VideoStreamConfig config); | 
|  |  | 
|  | AudioStreamPair* CreateAudioStream( | 
|  | std::pair<CallClient*, CallClient*> clients, | 
|  | std::function<void(AudioStreamConfig*)> config_modifier); | 
|  | AudioStreamPair* CreateAudioStream( | 
|  | std::pair<CallClient*, CallClient*> clients, | 
|  | AudioStreamConfig config); | 
|  |  | 
|  | // Runs the provided function with a fixed interval. For real time tests, | 
|  | // `function` starts being called after `interval` from the call to Every(). | 
|  | void Every(TimeDelta interval, absl::AnyInvocable<void(TimeDelta)> function); | 
|  | void Every(TimeDelta interval, absl::AnyInvocable<void()> function); | 
|  |  | 
|  | // Runs the provided function on the internal task queue. This ensure that | 
|  | // it's run on the main thread for simulated time tests. | 
|  | void Post(absl::AnyInvocable<void() &&> function); | 
|  |  | 
|  | // Runs the provided function after given duration has passed. For real time | 
|  | // tests, `function` is called after `target_time_since_start` from the call | 
|  | // to Every(). | 
|  | void At(TimeDelta offset, absl::AnyInvocable<void() &&> function); | 
|  |  | 
|  | // Sends a packet over the nodes and runs `action` when it has been delivered. | 
|  | void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes, | 
|  | size_t packet_size, | 
|  | std::function<void()> action); | 
|  |  | 
|  | // Runs the scenario for the given time. | 
|  | void RunFor(TimeDelta duration); | 
|  | // Runs the scenario until `target_time_since_start`. | 
|  | void RunUntil(TimeDelta target_time_since_start); | 
|  | // Runs the scenario until `target_time_since_start` or `exit_function` | 
|  | // returns true. `exit_function` is polled after each `check_interval` has | 
|  | // passed. | 
|  | void RunUntil(TimeDelta target_time_since_start, | 
|  | TimeDelta check_interval, | 
|  | std::function<bool()> exit_function); | 
|  | void Start(); | 
|  | void Stop(); | 
|  |  | 
|  | // Triggers sending of dummy packets over the given nodes. | 
|  | void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes, | 
|  | size_t num_packets, | 
|  | size_t packet_size); | 
|  |  | 
|  | ColumnPrinter TimePrinter(); | 
|  | StatesPrinter* CreatePrinter(absl::string_view name, | 
|  | TimeDelta interval, | 
|  | std::vector<ColumnPrinter> printers); | 
|  |  | 
|  | // Returns the current time. | 
|  | Timestamp Now(); | 
|  | // Return the duration of the current session so far. | 
|  | TimeDelta TimeSinceStart(); | 
|  |  | 
|  | std::unique_ptr<RtcEventLogOutput> GetLogWriter(absl::string_view name) { | 
|  | if (!log_writer_factory_ || name.empty()) | 
|  | return nullptr; | 
|  | return log_writer_factory_->Create(name); | 
|  | } | 
|  | std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory( | 
|  | absl::string_view name) { | 
|  | if (!log_writer_factory_ || name.empty()) | 
|  | return nullptr; | 
|  | return std::make_unique<LogWriterFactoryAddPrefix>( | 
|  | log_writer_factory_.get(), name); | 
|  | } | 
|  |  | 
|  | private: | 
|  | TimeDelta TimeUntilTarget(TimeDelta target_time_offset); | 
|  |  | 
|  | const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; | 
|  | NetworkEmulationManagerImpl network_manager_; | 
|  | Clock* clock_; | 
|  |  | 
|  | std::vector<std::unique_ptr<CallClient>> clients_; | 
|  | std::vector<std::unique_ptr<CallClientPair>> client_pairs_; | 
|  | std::vector<std::unique_ptr<VideoStreamPair>> video_streams_; | 
|  | std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_; | 
|  | std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_; | 
|  | std::vector<std::unique_ptr<StatesPrinter>> printers_; | 
|  |  | 
|  | rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_; | 
|  | rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_; | 
|  |  | 
|  | Timestamp start_time_ = Timestamp::PlusInfinity(); | 
|  | // Defined last so it's destroyed first. | 
|  | std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_; | 
|  | }; | 
|  | }  // namespace test | 
|  | }  // namespace webrtc | 
|  |  | 
|  | #endif  // TEST_SCENARIO_SCENARIO_H_ |