| /* |
| * 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 "api/test/time_controller.h" |
| #include "rtc_base/constructor_magic.h" |
| #include "rtc_base/fake_clock.h" |
| #include "rtc_base/task_queue.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(std::string file_name); |
| Scenario(std::string file_name, bool real_time); |
| Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager, |
| bool real_time); |
| RTC_DISALLOW_COPY_AND_ASSIGN(Scenario); |
| ~Scenario(); |
| 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(std::string name, CallClientConfig config); |
| CallClient* CreateClient( |
| std::string 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, std::function<void(TimeDelta)> function); |
| void Every(TimeDelta interval, std::function<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(std::function<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, std::function<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(std::string 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(std::string name) { |
| if (!log_writer_factory_ || name.empty()) |
| return nullptr; |
| return log_writer_factory_->Create(name); |
| } |
| std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory( |
| std::string 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. |
| rtc::TaskQueue task_queue_; |
| }; |
| } // namespace test |
| } // namespace webrtc |
| |
| #endif // TEST_SCENARIO_SCENARIO_H_ |