/* * 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 #include #include #include #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 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 config_modifier); SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config); SimulationNode* CreateMutableSimulationNode( std::function config_modifier); CallClient* CreateClient(std::string name, CallClientConfig config); CallClient* CreateClient( std::string name, std::function config_modifier); CallClientPair* CreateRoutes(CallClient* first, std::vector send_link, CallClient* second, std::vector return_link); CallClientPair* CreateRoutes(CallClient* first, std::vector send_link, DataSize first_overhead, CallClient* second, std::vector return_link, DataSize second_overhead); void ChangeRoute(std::pair clients, std::vector over_nodes); void ChangeRoute(std::pair clients, std::vector over_nodes, DataSize overhead); VideoStreamPair* CreateVideoStream( std::pair clients, std::function config_modifier); VideoStreamPair* CreateVideoStream( std::pair clients, VideoStreamConfig config); AudioStreamPair* CreateAudioStream( std::pair clients, std::function config_modifier); AudioStreamPair* CreateAudioStream( std::pair 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 function); void Every(TimeDelta interval, std::function 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 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 function); // Sends a packet over the nodes and runs |action| when it has been delivered. void NetworkDelayedAction(std::vector over_nodes, size_t packet_size, std::function 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 exit_function); void Start(); void Stop(); // Triggers sending of dummy packets over the given nodes. void TriggerPacketBurst(std::vector over_nodes, size_t num_packets, size_t packet_size); ColumnPrinter TimePrinter(); StatesPrinter* CreatePrinter(std::string name, TimeDelta interval, std::vector printers); // Returns the current time. Timestamp Now(); // Return the duration of the current session so far. TimeDelta TimeSinceStart(); std::unique_ptr GetLogWriter(std::string name) { if (!log_writer_factory_ || name.empty()) return nullptr; return log_writer_factory_->Create(name); } std::unique_ptr GetLogWriterFactory( std::string name) { if (!log_writer_factory_ || name.empty()) return nullptr; return std::make_unique( log_writer_factory_.get(), name); } private: TimeDelta TimeUntilTarget(TimeDelta target_time_offset); const std::unique_ptr log_writer_factory_; NetworkEmulationManagerImpl network_manager_; Clock* clock_; std::vector> clients_; std::vector> client_pairs_; std::vector> video_streams_; std::vector> audio_streams_; std::vector> simulation_nodes_; std::vector> printers_; rtc::scoped_refptr audio_decoder_factory_; rtc::scoped_refptr 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_