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