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