Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 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 | #include "test/scenario/scenario.h" |
| 11 | |
| 12 | #include <algorithm> |
Mirko Bonadei | 317a1f0 | 2019-09-17 17:06:18 +0200 | [diff] [blame] | 13 | #include <memory> |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 14 | |
Mirko Bonadei | 2ab97f6 | 2019-07-18 13:44:12 +0200 | [diff] [blame] | 15 | #include "absl/flags/flag.h" |
| 16 | #include "absl/flags/parse.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 17 | #include "api/audio_codecs/builtin_audio_decoder_factory.h" |
| 18 | #include "api/audio_codecs/builtin_audio_encoder_factory.h" |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 19 | #include "rtc_base/socket_address.h" |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 20 | #include "test/logging/file_log_writer.h" |
Artem Titov | 386802e | 2019-07-05 10:48:17 +0200 | [diff] [blame] | 21 | #include "test/network/network_emulation.h" |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 22 | #include "test/testsupport/file_utils.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 23 | |
Mirko Bonadei | 2ab97f6 | 2019-07-18 13:44:12 +0200 | [diff] [blame] | 24 | ABSL_FLAG(bool, scenario_logs, false, "Save logs from scenario framework."); |
| 25 | ABSL_FLAG(std::string, |
| 26 | scenario_logs_root, |
| 27 | "", |
| 28 | "Output root path, based on project root if unset."); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 29 | |
| 30 | namespace webrtc { |
| 31 | namespace test { |
| 32 | namespace { |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 33 | |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 34 | std::unique_ptr<FileLogWriterFactory> GetScenarioLogManager( |
| 35 | std::string file_name) { |
Mirko Bonadei | 2ab97f6 | 2019-07-18 13:44:12 +0200 | [diff] [blame] | 36 | if (absl::GetFlag(FLAGS_scenario_logs) && !file_name.empty()) { |
| 37 | std::string output_root = absl::GetFlag(FLAGS_scenario_logs_root); |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 38 | if (output_root.empty()) |
| 39 | output_root = OutputPath() + "output_data/"; |
| 40 | |
| 41 | auto base_filename = output_root + file_name + "."; |
| 42 | RTC_LOG(LS_INFO) << "Saving scenario logs to: " << base_filename; |
Mirko Bonadei | 317a1f0 | 2019-09-17 17:06:18 +0200 | [diff] [blame] | 43 | return std::make_unique<FileLogWriterFactory>(base_filename); |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 44 | } |
| 45 | return nullptr; |
| 46 | } |
Jonas Olsson | a4d8737 | 2019-07-05 19:08:33 +0200 | [diff] [blame] | 47 | } // namespace |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 48 | |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 49 | Scenario::Scenario() |
Sebastian Jansson | ebd94f6 | 2019-04-03 13:38:15 +0200 | [diff] [blame] | 50 | : Scenario(std::unique_ptr<LogWriterFactoryInterface>(), |
| 51 | /*real_time=*/false) {} |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 52 | |
Sebastian Jansson | 3d4d94a | 2020-01-14 14:25:41 +0100 | [diff] [blame] | 53 | Scenario::Scenario(const testing::TestInfo* test_info) |
| 54 | : Scenario(std::string(test_info->test_suite_name()) + "/" + |
| 55 | test_info->name()) {} |
| 56 | |
Sebastian Jansson | ebd94f6 | 2019-04-03 13:38:15 +0200 | [diff] [blame] | 57 | Scenario::Scenario(std::string file_name) |
| 58 | : Scenario(file_name, /*real_time=*/false) {} |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 59 | |
| 60 | Scenario::Scenario(std::string file_name, bool real_time) |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 61 | : Scenario(GetScenarioLogManager(file_name), real_time) {} |
| 62 | |
| 63 | Scenario::Scenario( |
| 64 | std::unique_ptr<LogWriterFactoryInterface> log_writer_factory, |
| 65 | bool real_time) |
| 66 | : log_writer_factory_(std::move(log_writer_factory)), |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 67 | network_manager_(real_time ? TimeMode::kRealTime : TimeMode::kSimulated), |
| 68 | clock_(network_manager_.time_controller()->GetClock()), |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 69 | audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()), |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 70 | audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()), |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 71 | task_queue_(network_manager_.time_controller() |
| 72 | ->GetTaskQueueFactory() |
| 73 | ->CreateTaskQueue("Scenario", |
| 74 | TaskQueueFactory::Priority::NORMAL)) {} |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 75 | |
| 76 | Scenario::~Scenario() { |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 77 | if (start_time_.IsFinite()) |
| 78 | Stop(); |
Sebastian Jansson | 77bd385 | 2020-01-17 13:05:54 +0100 | [diff] [blame] | 79 | for (auto& call_client : clients_) { |
Sebastian Jansson | 4124dab | 2019-04-01 14:33:53 +0200 | [diff] [blame] | 80 | call_client->transport_->Disconnect(); |
Sebastian Jansson | 77bd385 | 2020-01-17 13:05:54 +0100 | [diff] [blame] | 81 | call_client->UnBind(); |
| 82 | } |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | ColumnPrinter Scenario::TimePrinter() { |
Jonas Olsson | a4d8737 | 2019-07-05 19:08:33 +0200 | [diff] [blame] | 86 | return ColumnPrinter::Lambda( |
| 87 | "time", |
| 88 | [this](rtc::SimpleStringBuilder& sb) { |
| 89 | sb.AppendFormat("%.3lf", Now().seconds<double>()); |
| 90 | }, |
| 91 | 32); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | StatesPrinter* Scenario::CreatePrinter(std::string name, |
| 95 | TimeDelta interval, |
| 96 | std::vector<ColumnPrinter> printers) { |
| 97 | std::vector<ColumnPrinter> all_printers{TimePrinter()}; |
| 98 | for (auto& printer : printers) |
| 99 | all_printers.push_back(printer); |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 100 | StatesPrinter* printer = new StatesPrinter(GetLogWriter(name), all_printers); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 101 | printers_.emplace_back(printer); |
| 102 | printer->PrintHeaders(); |
| 103 | if (interval.IsFinite()) |
| 104 | Every(interval, [printer] { printer->PrintRow(); }); |
| 105 | return printer; |
| 106 | } |
| 107 | |
| 108 | CallClient* Scenario::CreateClient(std::string name, CallClientConfig config) { |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 109 | CallClient* client = new CallClient(network_manager_.time_controller(), |
| 110 | GetLogWriterFactory(name), config); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 111 | if (config.transport.state_log_interval.IsFinite()) { |
| 112 | Every(config.transport.state_log_interval, [this, client]() { |
| 113 | client->network_controller_factory_.LogCongestionControllerStats(Now()); |
| 114 | }); |
| 115 | } |
| 116 | clients_.emplace_back(client); |
| 117 | return client; |
| 118 | } |
| 119 | |
| 120 | CallClient* Scenario::CreateClient( |
| 121 | std::string name, |
| 122 | std::function<void(CallClientConfig*)> config_modifier) { |
| 123 | CallClientConfig config; |
| 124 | config_modifier(&config); |
| 125 | return CreateClient(name, config); |
| 126 | } |
| 127 | |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 128 | CallClientPair* Scenario::CreateRoutes( |
| 129 | CallClient* first, |
| 130 | std::vector<EmulatedNetworkNode*> send_link, |
| 131 | CallClient* second, |
| 132 | std::vector<EmulatedNetworkNode*> return_link) { |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 133 | return CreateRoutes(first, send_link, |
Danil Chapovalov | cad3e0e | 2020-02-17 18:46:07 +0100 | [diff] [blame] | 134 | DataSize::Bytes(PacketOverhead::kDefault), second, |
| 135 | return_link, DataSize::Bytes(PacketOverhead::kDefault)); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 136 | } |
| 137 | |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 138 | CallClientPair* Scenario::CreateRoutes( |
| 139 | CallClient* first, |
| 140 | std::vector<EmulatedNetworkNode*> send_link, |
| 141 | DataSize first_overhead, |
| 142 | CallClient* second, |
| 143 | std::vector<EmulatedNetworkNode*> return_link, |
| 144 | DataSize second_overhead) { |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 145 | CallClientPair* client_pair = new CallClientPair(first, second); |
| 146 | ChangeRoute(client_pair->forward(), send_link, first_overhead); |
| 147 | ChangeRoute(client_pair->reverse(), return_link, second_overhead); |
| 148 | client_pairs_.emplace_back(client_pair); |
| 149 | return client_pair; |
| 150 | } |
| 151 | |
| 152 | void Scenario::ChangeRoute(std::pair<CallClient*, CallClient*> clients, |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 153 | std::vector<EmulatedNetworkNode*> over_nodes) { |
Danil Chapovalov | cad3e0e | 2020-02-17 18:46:07 +0100 | [diff] [blame] | 154 | ChangeRoute(clients, over_nodes, DataSize::Bytes(PacketOverhead::kDefault)); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | void Scenario::ChangeRoute(std::pair<CallClient*, CallClient*> clients, |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 158 | std::vector<EmulatedNetworkNode*> over_nodes, |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 159 | DataSize overhead) { |
Sebastian Jansson | 77bd385 | 2020-01-17 13:05:54 +0100 | [diff] [blame] | 160 | EmulatedRoute* route = network_manager_.CreateRoute(over_nodes); |
| 161 | uint16_t port = clients.second->Bind(route->to); |
| 162 | auto addr = rtc::SocketAddress(route->to->GetPeerLocalAddress(), port); |
| 163 | clients.first->transport_->Connect(route->from, addr, overhead); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 164 | } |
| 165 | |
Sebastian Jansson | ef86d14 | 2019-04-15 14:42:42 +0200 | [diff] [blame] | 166 | EmulatedNetworkNode* Scenario::CreateSimulationNode( |
| 167 | std::function<void(NetworkSimulationConfig*)> config_modifier) { |
| 168 | NetworkSimulationConfig config; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 169 | config_modifier(&config); |
| 170 | return CreateSimulationNode(config); |
| 171 | } |
| 172 | |
Sebastian Jansson | ef86d14 | 2019-04-15 14:42:42 +0200 | [diff] [blame] | 173 | EmulatedNetworkNode* Scenario::CreateSimulationNode( |
| 174 | NetworkSimulationConfig config) { |
Sebastian Jansson | a4c22b9 | 2019-04-15 21:10:00 +0200 | [diff] [blame] | 175 | return network_manager_.CreateEmulatedNode( |
| 176 | SimulationNode::CreateBehavior(config)); |
Sebastian Jansson | ef86d14 | 2019-04-15 14:42:42 +0200 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | SimulationNode* Scenario::CreateMutableSimulationNode( |
| 180 | std::function<void(NetworkSimulationConfig*)> config_modifier) { |
| 181 | NetworkSimulationConfig config; |
| 182 | config_modifier(&config); |
| 183 | return CreateMutableSimulationNode(config); |
| 184 | } |
| 185 | |
| 186 | SimulationNode* Scenario::CreateMutableSimulationNode( |
| 187 | NetworkSimulationConfig config) { |
Sebastian Jansson | a4c22b9 | 2019-04-15 21:10:00 +0200 | [diff] [blame] | 188 | std::unique_ptr<SimulatedNetwork> behavior = |
| 189 | SimulationNode::CreateBehavior(config); |
| 190 | SimulatedNetwork* behavior_ptr = behavior.get(); |
| 191 | auto* emulated_node = |
| 192 | network_manager_.CreateEmulatedNode(std::move(behavior)); |
| 193 | simulation_nodes_.emplace_back( |
| 194 | new SimulationNode(config, behavior_ptr, emulated_node)); |
| 195 | return simulation_nodes_.back().get(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 196 | } |
| 197 | |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 198 | void Scenario::TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 199 | size_t num_packets, |
| 200 | size_t packet_size) { |
Andrey Logvin | f9ee0e0 | 2021-01-14 09:50:32 +0000 | [diff] [blame] | 201 | network_manager_.CreateCrossTrafficRoute(over_nodes) |
Sebastian Jansson | a4c22b9 | 2019-04-15 21:10:00 +0200 | [diff] [blame] | 202 | ->TriggerPacketBurst(num_packets, packet_size); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 203 | } |
| 204 | |
Artem Titov | 37d1848 | 2019-01-08 15:41:45 +0100 | [diff] [blame] | 205 | void Scenario::NetworkDelayedAction( |
| 206 | std::vector<EmulatedNetworkNode*> over_nodes, |
| 207 | size_t packet_size, |
| 208 | std::function<void()> action) { |
Andrey Logvin | f9ee0e0 | 2021-01-14 09:50:32 +0000 | [diff] [blame] | 209 | network_manager_.CreateCrossTrafficRoute(over_nodes) |
Sebastian Jansson | a4c22b9 | 2019-04-15 21:10:00 +0200 | [diff] [blame] | 210 | ->NetworkDelayedAction(packet_size, action); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 211 | } |
| 212 | |
| 213 | VideoStreamPair* Scenario::CreateVideoStream( |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 214 | std::pair<CallClient*, CallClient*> clients, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 215 | std::function<void(VideoStreamConfig*)> config_modifier) { |
| 216 | VideoStreamConfig config; |
| 217 | config_modifier(&config); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 218 | return CreateVideoStream(clients, config); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 219 | } |
| 220 | |
| 221 | VideoStreamPair* Scenario::CreateVideoStream( |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 222 | std::pair<CallClient*, CallClient*> clients, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 223 | VideoStreamConfig config) { |
Sebastian Jansson | cf2df2f | 2019-04-02 11:51:28 +0200 | [diff] [blame] | 224 | video_streams_.emplace_back( |
| 225 | new VideoStreamPair(clients.first, clients.second, config)); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 226 | return video_streams_.back().get(); |
| 227 | } |
| 228 | |
| 229 | AudioStreamPair* Scenario::CreateAudioStream( |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 230 | std::pair<CallClient*, CallClient*> clients, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 231 | std::function<void(AudioStreamConfig*)> config_modifier) { |
| 232 | AudioStreamConfig config; |
| 233 | config_modifier(&config); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 234 | return CreateAudioStream(clients, config); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 235 | } |
| 236 | |
| 237 | AudioStreamPair* Scenario::CreateAudioStream( |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 238 | std::pair<CallClient*, CallClient*> clients, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 239 | AudioStreamConfig config) { |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 240 | audio_streams_.emplace_back( |
| 241 | new AudioStreamPair(clients.first, audio_encoder_factory_, clients.second, |
| 242 | audio_decoder_factory_, config)); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 243 | return audio_streams_.back().get(); |
| 244 | } |
| 245 | |
Sebastian Jansson | 123f345 | 2019-03-13 11:22:52 +0100 | [diff] [blame] | 246 | void Scenario::Every(TimeDelta interval, |
| 247 | std::function<void(TimeDelta)> function) { |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 248 | RepeatingTaskHandle::DelayedStart(task_queue_.Get(), interval, |
| 249 | [interval, function] { |
| 250 | function(interval); |
| 251 | return interval; |
| 252 | }); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 253 | } |
| 254 | |
Sebastian Jansson | 123f345 | 2019-03-13 11:22:52 +0100 | [diff] [blame] | 255 | void Scenario::Every(TimeDelta interval, std::function<void()> function) { |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 256 | RepeatingTaskHandle::DelayedStart(task_queue_.Get(), interval, |
| 257 | [interval, function] { |
| 258 | function(); |
| 259 | return interval; |
| 260 | }); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 261 | } |
| 262 | |
Sebastian Jansson | 3d4d94a | 2020-01-14 14:25:41 +0100 | [diff] [blame] | 263 | void Scenario::Post(std::function<void()> function) { |
| 264 | task_queue_.PostTask(function); |
| 265 | } |
| 266 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 267 | void Scenario::At(TimeDelta offset, std::function<void()> function) { |
Sebastian Jansson | 5a00016 | 2019-04-12 11:21:32 +0200 | [diff] [blame] | 268 | RTC_DCHECK_GT(offset, TimeSinceStart()); |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 269 | task_queue_.PostDelayedTask(function, TimeUntilTarget(offset).ms()); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 270 | } |
| 271 | |
| 272 | void Scenario::RunFor(TimeDelta duration) { |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 273 | if (start_time_.IsInfinite()) |
| 274 | Start(); |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 275 | network_manager_.time_controller()->AdvanceTime(duration); |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 276 | } |
| 277 | |
Sebastian Jansson | 123f345 | 2019-03-13 11:22:52 +0100 | [diff] [blame] | 278 | void Scenario::RunUntil(TimeDelta target_time_since_start) { |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 279 | RunFor(TimeUntilTarget(target_time_since_start)); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 280 | } |
| 281 | |
Sebastian Jansson | 123f345 | 2019-03-13 11:22:52 +0100 | [diff] [blame] | 282 | void Scenario::RunUntil(TimeDelta target_time_since_start, |
| 283 | TimeDelta check_interval, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 284 | std::function<bool()> exit_function) { |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 285 | if (start_time_.IsInfinite()) |
| 286 | Start(); |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 287 | while (check_interval >= TimeUntilTarget(target_time_since_start)) { |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 288 | network_manager_.time_controller()->AdvanceTime(check_interval); |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 289 | if (exit_function()) |
| 290 | return; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 291 | } |
Sebastian Jansson | 6ce033a | 2020-01-22 10:12:56 +0100 | [diff] [blame] | 292 | network_manager_.time_controller()->AdvanceTime( |
| 293 | TimeUntilTarget(target_time_since_start)); |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 294 | } |
| 295 | |
| 296 | void Scenario::Start() { |
Sebastian Jansson | b64ad0e | 2019-06-19 09:39:34 +0200 | [diff] [blame] | 297 | start_time_ = clock_->CurrentTime(); |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 298 | for (auto& stream_pair : video_streams_) |
| 299 | stream_pair->receive()->Start(); |
| 300 | for (auto& stream_pair : audio_streams_) |
| 301 | stream_pair->receive()->Start(); |
| 302 | for (auto& stream_pair : video_streams_) { |
| 303 | if (stream_pair->config_.autostart) { |
| 304 | stream_pair->send()->Start(); |
| 305 | } |
| 306 | } |
| 307 | for (auto& stream_pair : audio_streams_) { |
| 308 | if (stream_pair->config_.autostart) { |
| 309 | stream_pair->send()->Start(); |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | void Scenario::Stop() { |
| 315 | RTC_DCHECK(start_time_.IsFinite()); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 316 | for (auto& stream_pair : video_streams_) { |
Sebastian Jansson | bdfadd6 | 2019-02-08 13:34:57 +0100 | [diff] [blame] | 317 | stream_pair->send()->Stop(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 318 | } |
| 319 | for (auto& stream_pair : audio_streams_) |
Sebastian Jansson | bdfadd6 | 2019-02-08 13:34:57 +0100 | [diff] [blame] | 320 | stream_pair->send()->Stop(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 321 | for (auto& stream_pair : video_streams_) |
Sebastian Jansson | bdfadd6 | 2019-02-08 13:34:57 +0100 | [diff] [blame] | 322 | stream_pair->receive()->Stop(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 323 | for (auto& stream_pair : audio_streams_) |
Sebastian Jansson | bdfadd6 | 2019-02-08 13:34:57 +0100 | [diff] [blame] | 324 | stream_pair->receive()->Stop(); |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 325 | start_time_ = Timestamp::PlusInfinity(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 326 | } |
| 327 | |
| 328 | Timestamp Scenario::Now() { |
Sebastian Jansson | b64ad0e | 2019-06-19 09:39:34 +0200 | [diff] [blame] | 329 | return clock_->CurrentTime(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 330 | } |
| 331 | |
Sebastian Jansson | 123f345 | 2019-03-13 11:22:52 +0100 | [diff] [blame] | 332 | TimeDelta Scenario::TimeSinceStart() { |
Sebastian Jansson | 49a7843 | 2018-11-20 16:15:29 +0100 | [diff] [blame] | 333 | if (start_time_.IsInfinite()) |
| 334 | return TimeDelta::Zero(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 335 | return Now() - start_time_; |
| 336 | } |
| 337 | |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 338 | TimeDelta Scenario::TimeUntilTarget(TimeDelta target_time_offset) { |
| 339 | return target_time_offset - TimeSinceStart(); |
| 340 | } |
| 341 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 342 | } // namespace test |
| 343 | } // namespace webrtc |