1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker #ifndef TEST_SCENARIO_SCENARIO_H_ 11*d9f75844SAndroid Build Coastguard Worker #define TEST_SCENARIO_SCENARIO_H_ 12*d9f75844SAndroid Build Coastguard Worker #include <memory> 13*d9f75844SAndroid Build Coastguard Worker #include <string> 14*d9f75844SAndroid Build Coastguard Worker #include <utility> 15*d9f75844SAndroid Build Coastguard Worker #include <vector> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "absl/functional/any_invocable.h" 18*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h" 19*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/test/time_controller.h" 21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_clock.h" 22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_utils/repeating_task.h" 23*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h" 24*d9f75844SAndroid Build Coastguard Worker #include "test/logging/log_writer.h" 25*d9f75844SAndroid Build Coastguard Worker #include "test/network/network_emulation_manager.h" 26*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/audio_stream.h" 27*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/call_client.h" 28*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/column_printer.h" 29*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/network_node.h" 30*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/scenario_config.h" 31*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/video_stream.h" 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 34*d9f75844SAndroid Build Coastguard Worker namespace test { 35*d9f75844SAndroid Build Coastguard Worker // Scenario is a class owning everything for a test scenario. It creates and 36*d9f75844SAndroid Build Coastguard Worker // holds network nodes, call clients and media streams. It also provides methods 37*d9f75844SAndroid Build Coastguard Worker // for changing behavior at runtime. Since it always keeps ownership of the 38*d9f75844SAndroid Build Coastguard Worker // created components, it generally returns non-owning pointers. It maintains 39*d9f75844SAndroid Build Coastguard Worker // the life of its objects until it is destroyed. 40*d9f75844SAndroid Build Coastguard Worker // For methods accepting configuration structs, a modifier function interface is 41*d9f75844SAndroid Build Coastguard Worker // generally provided. This allows simple partial overriding of the default 42*d9f75844SAndroid Build Coastguard Worker // configuration. 43*d9f75844SAndroid Build Coastguard Worker class Scenario { 44*d9f75844SAndroid Build Coastguard Worker public: 45*d9f75844SAndroid Build Coastguard Worker Scenario(); 46*d9f75844SAndroid Build Coastguard Worker explicit Scenario(const testing::TestInfo* test_info); 47*d9f75844SAndroid Build Coastguard Worker explicit Scenario(absl::string_view file_name); 48*d9f75844SAndroid Build Coastguard Worker Scenario(absl::string_view file_name, bool real_time); 49*d9f75844SAndroid Build Coastguard Worker Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager, 50*d9f75844SAndroid Build Coastguard Worker bool real_time); 51*d9f75844SAndroid Build Coastguard Worker 52*d9f75844SAndroid Build Coastguard Worker ~Scenario(); 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker Scenario(const Scenario&) = delete; 55*d9f75844SAndroid Build Coastguard Worker Scenario& operator=(const Scenario&) = delete; 56*d9f75844SAndroid Build Coastguard Worker net()57*d9f75844SAndroid Build Coastguard Worker NetworkEmulationManagerImpl* net() { return &network_manager_; } 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config); 60*d9f75844SAndroid Build Coastguard Worker EmulatedNetworkNode* CreateSimulationNode( 61*d9f75844SAndroid Build Coastguard Worker std::function<void(NetworkSimulationConfig*)> config_modifier); 62*d9f75844SAndroid Build Coastguard Worker 63*d9f75844SAndroid Build Coastguard Worker SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config); 64*d9f75844SAndroid Build Coastguard Worker SimulationNode* CreateMutableSimulationNode( 65*d9f75844SAndroid Build Coastguard Worker std::function<void(NetworkSimulationConfig*)> config_modifier); 66*d9f75844SAndroid Build Coastguard Worker 67*d9f75844SAndroid Build Coastguard Worker CallClient* CreateClient(absl::string_view name, CallClientConfig config); 68*d9f75844SAndroid Build Coastguard Worker CallClient* CreateClient( 69*d9f75844SAndroid Build Coastguard Worker absl::string_view name, 70*d9f75844SAndroid Build Coastguard Worker std::function<void(CallClientConfig*)> config_modifier); 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Worker CallClientPair* CreateRoutes(CallClient* first, 73*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> send_link, 74*d9f75844SAndroid Build Coastguard Worker CallClient* second, 75*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> return_link); 76*d9f75844SAndroid Build Coastguard Worker 77*d9f75844SAndroid Build Coastguard Worker CallClientPair* CreateRoutes(CallClient* first, 78*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> send_link, 79*d9f75844SAndroid Build Coastguard Worker DataSize first_overhead, 80*d9f75844SAndroid Build Coastguard Worker CallClient* second, 81*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> return_link, 82*d9f75844SAndroid Build Coastguard Worker DataSize second_overhead); 83*d9f75844SAndroid Build Coastguard Worker 84*d9f75844SAndroid Build Coastguard Worker void ChangeRoute(std::pair<CallClient*, CallClient*> clients, 85*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> over_nodes); 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker void ChangeRoute(std::pair<CallClient*, CallClient*> clients, 88*d9f75844SAndroid Build Coastguard Worker std::vector<EmulatedNetworkNode*> over_nodes, 89*d9f75844SAndroid Build Coastguard Worker DataSize overhead); 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker VideoStreamPair* CreateVideoStream( 92*d9f75844SAndroid Build Coastguard Worker std::pair<CallClient*, CallClient*> clients, 93*d9f75844SAndroid Build Coastguard Worker std::function<void(VideoStreamConfig*)> config_modifier); 94*d9f75844SAndroid Build Coastguard Worker VideoStreamPair* CreateVideoStream( 95*d9f75844SAndroid Build Coastguard Worker std::pair<CallClient*, CallClient*> clients, 96*d9f75844SAndroid Build Coastguard Worker VideoStreamConfig config); 97*d9f75844SAndroid Build Coastguard Worker 98*d9f75844SAndroid Build Coastguard Worker AudioStreamPair* CreateAudioStream( 99*d9f75844SAndroid Build Coastguard Worker std::pair<CallClient*, CallClient*> clients, 100*d9f75844SAndroid Build Coastguard Worker std::function<void(AudioStreamConfig*)> config_modifier); 101*d9f75844SAndroid Build Coastguard Worker AudioStreamPair* CreateAudioStream( 102*d9f75844SAndroid Build Coastguard Worker std::pair<CallClient*, CallClient*> clients, 103*d9f75844SAndroid Build Coastguard Worker AudioStreamConfig config); 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker // Runs the provided function with a fixed interval. For real time tests, 106*d9f75844SAndroid Build Coastguard Worker // `function` starts being called after `interval` from the call to Every(). 107*d9f75844SAndroid Build Coastguard Worker void Every(TimeDelta interval, absl::AnyInvocable<void(TimeDelta)> function); 108*d9f75844SAndroid Build Coastguard Worker void Every(TimeDelta interval, absl::AnyInvocable<void()> function); 109*d9f75844SAndroid Build Coastguard Worker 110*d9f75844SAndroid Build Coastguard Worker // Runs the provided function on the internal task queue. This ensure that 111*d9f75844SAndroid Build Coastguard Worker // it's run on the main thread for simulated time tests. 112*d9f75844SAndroid Build Coastguard Worker void Post(absl::AnyInvocable<void() &&> function); 113*d9f75844SAndroid Build Coastguard Worker 114*d9f75844SAndroid Build Coastguard Worker // Runs the provided function after given duration has passed. For real time 115*d9f75844SAndroid Build Coastguard Worker // tests, `function` is called after `target_time_since_start` from the call 116*d9f75844SAndroid Build Coastguard Worker // to Every(). 117*d9f75844SAndroid Build Coastguard Worker void At(TimeDelta offset, absl::AnyInvocable<void() &&> function); 118*d9f75844SAndroid Build Coastguard Worker 119*d9f75844SAndroid Build Coastguard Worker // Sends a packet over the nodes and runs `action` when it has been delivered. 120*d9f75844SAndroid Build Coastguard Worker void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes, 121*d9f75844SAndroid Build Coastguard Worker size_t packet_size, 122*d9f75844SAndroid Build Coastguard Worker std::function<void()> action); 123*d9f75844SAndroid Build Coastguard Worker 124*d9f75844SAndroid Build Coastguard Worker // Runs the scenario for the given time. 125*d9f75844SAndroid Build Coastguard Worker void RunFor(TimeDelta duration); 126*d9f75844SAndroid Build Coastguard Worker // Runs the scenario until `target_time_since_start`. 127*d9f75844SAndroid Build Coastguard Worker void RunUntil(TimeDelta target_time_since_start); 128*d9f75844SAndroid Build Coastguard Worker // Runs the scenario until `target_time_since_start` or `exit_function` 129*d9f75844SAndroid Build Coastguard Worker // returns true. `exit_function` is polled after each `check_interval` has 130*d9f75844SAndroid Build Coastguard Worker // passed. 131*d9f75844SAndroid Build Coastguard Worker void RunUntil(TimeDelta target_time_since_start, 132*d9f75844SAndroid Build Coastguard Worker TimeDelta check_interval, 133*d9f75844SAndroid Build Coastguard Worker std::function<bool()> exit_function); 134*d9f75844SAndroid Build Coastguard Worker void Start(); 135*d9f75844SAndroid Build Coastguard Worker void Stop(); 136*d9f75844SAndroid Build Coastguard Worker 137*d9f75844SAndroid Build Coastguard Worker // Triggers sending of dummy packets over the given nodes. 138*d9f75844SAndroid Build Coastguard Worker void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes, 139*d9f75844SAndroid Build Coastguard Worker size_t num_packets, 140*d9f75844SAndroid Build Coastguard Worker size_t packet_size); 141*d9f75844SAndroid Build Coastguard Worker 142*d9f75844SAndroid Build Coastguard Worker ColumnPrinter TimePrinter(); 143*d9f75844SAndroid Build Coastguard Worker StatesPrinter* CreatePrinter(absl::string_view name, 144*d9f75844SAndroid Build Coastguard Worker TimeDelta interval, 145*d9f75844SAndroid Build Coastguard Worker std::vector<ColumnPrinter> printers); 146*d9f75844SAndroid Build Coastguard Worker 147*d9f75844SAndroid Build Coastguard Worker // Returns the current time. 148*d9f75844SAndroid Build Coastguard Worker Timestamp Now(); 149*d9f75844SAndroid Build Coastguard Worker // Return the duration of the current session so far. 150*d9f75844SAndroid Build Coastguard Worker TimeDelta TimeSinceStart(); 151*d9f75844SAndroid Build Coastguard Worker GetLogWriter(absl::string_view name)152*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RtcEventLogOutput> GetLogWriter(absl::string_view name) { 153*d9f75844SAndroid Build Coastguard Worker if (!log_writer_factory_ || name.empty()) 154*d9f75844SAndroid Build Coastguard Worker return nullptr; 155*d9f75844SAndroid Build Coastguard Worker return log_writer_factory_->Create(name); 156*d9f75844SAndroid Build Coastguard Worker } GetLogWriterFactory(absl::string_view name)157*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory( 158*d9f75844SAndroid Build Coastguard Worker absl::string_view name) { 159*d9f75844SAndroid Build Coastguard Worker if (!log_writer_factory_ || name.empty()) 160*d9f75844SAndroid Build Coastguard Worker return nullptr; 161*d9f75844SAndroid Build Coastguard Worker return std::make_unique<LogWriterFactoryAddPrefix>( 162*d9f75844SAndroid Build Coastguard Worker log_writer_factory_.get(), name); 163*d9f75844SAndroid Build Coastguard Worker } 164*d9f75844SAndroid Build Coastguard Worker 165*d9f75844SAndroid Build Coastguard Worker private: 166*d9f75844SAndroid Build Coastguard Worker TimeDelta TimeUntilTarget(TimeDelta target_time_offset); 167*d9f75844SAndroid Build Coastguard Worker 168*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; 169*d9f75844SAndroid Build Coastguard Worker NetworkEmulationManagerImpl network_manager_; 170*d9f75844SAndroid Build Coastguard Worker Clock* clock_; 171*d9f75844SAndroid Build Coastguard Worker 172*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<CallClient>> clients_; 173*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<CallClientPair>> client_pairs_; 174*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<VideoStreamPair>> video_streams_; 175*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_; 176*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_; 177*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<StatesPrinter>> printers_; 178*d9f75844SAndroid Build Coastguard Worker 179*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_; 180*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_; 181*d9f75844SAndroid Build Coastguard Worker 182*d9f75844SAndroid Build Coastguard Worker Timestamp start_time_ = Timestamp::PlusInfinity(); 183*d9f75844SAndroid Build Coastguard Worker // Defined last so it's destroyed first. 184*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_; 185*d9f75844SAndroid Build Coastguard Worker }; 186*d9f75844SAndroid Build Coastguard Worker } // namespace test 187*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 188*d9f75844SAndroid Build Coastguard Worker 189*d9f75844SAndroid Build Coastguard Worker #endif // TEST_SCENARIO_SCENARIO_H_ 190