/* * 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 "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 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 config_modifier); SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config); SimulationNode* CreateMutableSimulationNode( std::function config_modifier); CallClient* CreateClient(absl::string_view name, CallClientConfig config); CallClient* CreateClient( absl::string_view 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, absl::AnyInvocable function); void Every(TimeDelta interval, absl::AnyInvocable 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 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 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(absl::string_view 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(absl::string_view name) { if (!log_writer_factory_ || name.empty()) return nullptr; return log_writer_factory_->Create(name); } std::unique_ptr GetLogWriterFactory( absl::string_view 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. std::unique_ptr task_queue_; }; } // namespace test } // namespace webrtc #endif // TEST_SCENARIO_SCENARIO_H_