blob: 1799ef38fbd35930f27fc510935304ca5e06e82a [file] [log] [blame]
Sebastian Jansson98b07e92018-09-27 13:47:01 +02001/*
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
Sebastian Jansson52de8b02019-01-16 17:25:44 +010017#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/constructor_magic.h"
19#include "rtc_base/fake_clock.h"
Sebastian Jansson105a10a2019-04-01 09:18:14 +020020#include "rtc_base/task_queue.h"
21#include "rtc_base/task_utils/repeating_task.h"
Sebastian Jansson52de8b02019-01-16 17:25:44 +010022#include "test/logging/log_writer.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020023#include "test/scenario/audio_stream.h"
24#include "test/scenario/call_client.h"
25#include "test/scenario/column_printer.h"
Sebastian Janssona4c22b92019-04-15 21:10:00 +020026#include "test/scenario/network/network_emulation_manager.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020027#include "test/scenario/network_node.h"
28#include "test/scenario/scenario_config.h"
Sebastian Jansson71a091e2018-09-27 19:08:21 +020029#include "test/scenario/simulated_time.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020030#include "test/scenario/video_stream.h"
Sebastian Jansson105a10a2019-04-01 09:18:14 +020031#include "test/time_controller/time_controller.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020032
33namespace webrtc {
34namespace test {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020035// 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.
43class Scenario {
44 public:
45 Scenario();
46 explicit Scenario(std::string file_name);
47 Scenario(std::string file_name, bool real_time);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010048 Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
49 bool real_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020050 RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
51 ~Scenario();
Sebastian Janssona4c22b92019-04-15 21:10:00 +020052 NetworkEmulationManagerImpl* net() { return &network_manager_; }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020053
Sebastian Janssonef86d142019-04-15 14:42:42 +020054 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);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020061
62 CallClient* CreateClient(std::string name, CallClientConfig config);
63 CallClient* CreateClient(
64 std::string name,
65 std::function<void(CallClientConfig*)> config_modifier);
66
Sebastian Jansson800e1212018-10-22 11:49:03 +020067 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010068 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020069 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010070 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020071
72 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010073 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020074 DataSize first_overhead,
75 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010076 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020077 DataSize second_overhead);
78
79 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010080 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020081
82 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010083 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020084 DataSize overhead);
85
Sebastian Jansson71a091e2018-09-27 19:08:21 +020086 SimulatedTimeClient* CreateSimulatedTimeClient(
87 std::string name,
88 SimulatedTimeClientConfig config,
89 std::vector<PacketStreamConfig> stream_configs,
Artem Titov37d18482019-01-08 15:41:45 +010090 std::vector<EmulatedNetworkNode*> send_link,
91 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson71a091e2018-09-27 19:08:21 +020092
Sebastian Jansson98b07e92018-09-27 13:47:01 +020093 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020094 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020095 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020096 VideoStreamPair* CreateVideoStream(
97 std::pair<CallClient*, CallClient*> clients,
98 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020099
100 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200101 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200102 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200103 AudioStreamPair* CreateAudioStream(
104 std::pair<CallClient*, CallClient*> clients,
105 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200106
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200107 // Runs the provided function with a fixed interval. For real time tests,
108 // |function| starts being called after |interval| from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100109 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
110 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200111
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200112 // Runs the provided function after given duration has passed. For real time
113 // tests, |function| is called after |target_time_since_start| from the call
114 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115 void At(TimeDelta offset, std::function<void()> function);
116
117 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100118 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200119 size_t packet_size,
120 std::function<void()> action);
121
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200122 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200123 void RunFor(TimeDelta duration);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200124 // Runs the scenario until |target_time_since_start|.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100125 void RunUntil(TimeDelta target_time_since_start);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200126 // Runs the scenario until |target_time_since_start| or |exit_function|
127 // returns true. |exit_function| is polled after each |check_interval| has
128 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100129 void RunUntil(TimeDelta target_time_since_start,
130 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200131 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100132 void Start();
133 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200134
135 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100136 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200137 size_t num_packets,
138 size_t packet_size);
139
140 ColumnPrinter TimePrinter();
141 StatesPrinter* CreatePrinter(std::string name,
142 TimeDelta interval,
143 std::vector<ColumnPrinter> printers);
144
145 // Returns the current time.
146 Timestamp Now();
147 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100148 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200149
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100150 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
151 if (!log_writer_factory_ || name.empty())
152 return nullptr;
153 return log_writer_factory_->Create(name);
154 }
155 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
156 std::string name) {
157 if (!log_writer_factory_ || name.empty())
158 return nullptr;
159 return absl::make_unique<LogWriterFactoryAddPrefix>(
160 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200161 }
162
163 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200164 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
165
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200166 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
167 std::unique_ptr<TimeController> time_controller_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200168 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200169
170 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200171 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200172 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
173 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200174 std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200175 std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200176 std::vector<std::unique_ptr<StatesPrinter>> printers_;
177
Sebastian Jansson800e1212018-10-22 11:49:03 +0200178 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200179 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
180 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
181
182 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200183 NetworkEmulationManagerImpl network_manager_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200184 // Defined last so it's destroyed first.
185 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200186};
187} // namespace test
188} // namespace webrtc
189
190#endif // TEST_SCENARIO_SCENARIO_H_