blob: fb4f0bb1760e2ac3263329176426b72930bd0c88 [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"
26#include "test/scenario/network_node.h"
27#include "test/scenario/scenario_config.h"
Sebastian Jansson71a091e2018-09-27 19:08:21 +020028#include "test/scenario/simulated_time.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020029#include "test/scenario/video_stream.h"
Sebastian Jansson105a10a2019-04-01 09:18:14 +020030#include "test/time_controller/time_controller.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020031
32namespace webrtc {
33namespace test {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020034// 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.
42class Scenario {
43 public:
44 Scenario();
45 explicit Scenario(std::string file_name);
46 Scenario(std::string file_name, bool real_time);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010047 Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
48 bool real_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020049 RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
50 ~Scenario();
51
Sebastian Janssonef86d142019-04-15 14:42:42 +020052 EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
53 EmulatedNetworkNode* CreateSimulationNode(
54 std::function<void(NetworkSimulationConfig*)> config_modifier);
55
56 SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config);
57 SimulationNode* CreateMutableSimulationNode(
58 std::function<void(NetworkSimulationConfig*)> config_modifier);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020059
60 CallClient* CreateClient(std::string name, CallClientConfig config);
61 CallClient* CreateClient(
62 std::string name,
63 std::function<void(CallClientConfig*)> config_modifier);
64
Sebastian Jansson800e1212018-10-22 11:49:03 +020065 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010066 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020067 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010068 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020069
70 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010071 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020072 DataSize first_overhead,
73 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010074 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020075 DataSize second_overhead);
76
77 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010078 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020079
80 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010081 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020082 DataSize overhead);
83
Sebastian Jansson71a091e2018-09-27 19:08:21 +020084 SimulatedTimeClient* CreateSimulatedTimeClient(
85 std::string name,
86 SimulatedTimeClientConfig config,
87 std::vector<PacketStreamConfig> stream_configs,
Artem Titov37d18482019-01-08 15:41:45 +010088 std::vector<EmulatedNetworkNode*> send_link,
89 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson71a091e2018-09-27 19:08:21 +020090
Sebastian Jansson98b07e92018-09-27 13:47:01 +020091 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020092 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020093 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020094 VideoStreamPair* CreateVideoStream(
95 std::pair<CallClient*, CallClient*> clients,
96 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020097
98 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020099 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200100 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200101 AudioStreamPair* CreateAudioStream(
102 std::pair<CallClient*, CallClient*> clients,
103 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200104
105 CrossTrafficSource* CreateCrossTraffic(
Artem Titov37d18482019-01-08 15:41:45 +0100106 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200107 std::function<void(CrossTrafficConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +0100108 CrossTrafficSource* CreateCrossTraffic(
109 std::vector<EmulatedNetworkNode*> over_nodes,
110 CrossTrafficConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200111
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200112 // Runs the provided function with a fixed interval. For real time tests,
113 // |function| starts being called after |interval| from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100114 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
115 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200116
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200117 // Runs the provided function after given duration has passed. For real time
118 // tests, |function| is called after |target_time_since_start| from the call
119 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200120 void At(TimeDelta offset, std::function<void()> function);
121
122 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100123 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200124 size_t packet_size,
125 std::function<void()> action);
126
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200127 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200128 void RunFor(TimeDelta duration);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200129 // Runs the scenario until |target_time_since_start|.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100130 void RunUntil(TimeDelta target_time_since_start);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200131 // Runs the scenario until |target_time_since_start| or |exit_function|
132 // returns true. |exit_function| is polled after each |check_interval| has
133 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100134 void RunUntil(TimeDelta target_time_since_start,
135 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200136 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100137 void Start();
138 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200139
140 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100141 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200142 size_t num_packets,
143 size_t packet_size);
144
145 ColumnPrinter TimePrinter();
146 StatesPrinter* CreatePrinter(std::string name,
147 TimeDelta interval,
148 std::vector<ColumnPrinter> printers);
149
150 // Returns the current time.
151 Timestamp Now();
152 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100153 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200154
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100155 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
156 if (!log_writer_factory_ || name.empty())
157 return nullptr;
158 return log_writer_factory_->Create(name);
159 }
160 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
161 std::string name) {
162 if (!log_writer_factory_ || name.empty())
163 return nullptr;
164 return absl::make_unique<LogWriterFactoryAddPrefix>(
165 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200166 }
167
168 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200169 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
170
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200171 NullReceiver null_receiver_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200172 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
173 std::unique_ptr<TimeController> time_controller_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200174 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200175
176 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200177 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Artem Titov37d18482019-01-08 15:41:45 +0100178 std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200179 std::vector<std::unique_ptr<CrossTrafficSource>> cross_traffic_sources_;
180 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
181 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
182
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200183 std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
184
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200185 std::vector<std::unique_ptr<ActionReceiver>> action_receivers_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200186 std::vector<std::unique_ptr<StatesPrinter>> printers_;
187
Sebastian Jansson800e1212018-10-22 11:49:03 +0200188 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200189 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
190 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
191
192 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200193 // Defined last so it's destroyed first.
194 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200195};
196} // namespace test
197} // namespace webrtc
198
199#endif // TEST_SCENARIO_SCENARIO_H_