blob: cf949df51732d1d22fe29a6d1e5f0492b02f899f [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
52 SimulationNode* CreateSimulationNode(NetworkNodeConfig config);
53 SimulationNode* CreateSimulationNode(
54 std::function<void(NetworkNodeConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +010055 EmulatedNetworkNode* CreateNetworkNode(
Artem Titov8ea1e9d2018-10-04 14:46:31 +020056 std::unique_ptr<NetworkBehaviorInterface> behavior);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020057
58 CallClient* CreateClient(std::string name, CallClientConfig config);
59 CallClient* CreateClient(
60 std::string name,
61 std::function<void(CallClientConfig*)> config_modifier);
62
Sebastian Jansson800e1212018-10-22 11:49:03 +020063 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010064 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020065 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010066 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020067
68 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010069 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020070 DataSize first_overhead,
71 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010072 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020073 DataSize second_overhead);
74
75 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010076 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020077
78 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010079 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020080 DataSize overhead);
81
Sebastian Jansson71a091e2018-09-27 19:08:21 +020082 SimulatedTimeClient* CreateSimulatedTimeClient(
83 std::string name,
84 SimulatedTimeClientConfig config,
85 std::vector<PacketStreamConfig> stream_configs,
Artem Titov37d18482019-01-08 15:41:45 +010086 std::vector<EmulatedNetworkNode*> send_link,
87 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson71a091e2018-09-27 19:08:21 +020088
Sebastian Jansson98b07e92018-09-27 13:47:01 +020089 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020090 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020091 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020092 VideoStreamPair* CreateVideoStream(
93 std::pair<CallClient*, CallClient*> clients,
94 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020095
96 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020097 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020098 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020099 AudioStreamPair* CreateAudioStream(
100 std::pair<CallClient*, CallClient*> clients,
101 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200102
103 CrossTrafficSource* CreateCrossTraffic(
Artem Titov37d18482019-01-08 15:41:45 +0100104 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200105 std::function<void(CrossTrafficConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +0100106 CrossTrafficSource* CreateCrossTraffic(
107 std::vector<EmulatedNetworkNode*> over_nodes,
108 CrossTrafficConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200109
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200110 // Runs the provided function with a fixed interval. For real time tests,
111 // |function| starts being called after |interval| from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100112 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
113 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200114
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200115 // Runs the provided function after given duration has passed. For real time
116 // tests, |function| is called after |target_time_since_start| from the call
117 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200118 void At(TimeDelta offset, std::function<void()> function);
119
120 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100121 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200122 size_t packet_size,
123 std::function<void()> action);
124
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200125 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200126 void RunFor(TimeDelta duration);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200127 // Runs the scenario until |target_time_since_start|.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100128 void RunUntil(TimeDelta target_time_since_start);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200129 // Runs the scenario until |target_time_since_start| or |exit_function|
130 // returns true. |exit_function| is polled after each |check_interval| has
131 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100132 void RunUntil(TimeDelta target_time_since_start,
133 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200134 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100135 void Start();
136 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200137
138 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100139 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200140 size_t num_packets,
141 size_t packet_size);
142
143 ColumnPrinter TimePrinter();
144 StatesPrinter* CreatePrinter(std::string name,
145 TimeDelta interval,
146 std::vector<ColumnPrinter> printers);
147
148 // Returns the current time.
149 Timestamp Now();
150 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100151 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200152
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100153 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
154 if (!log_writer_factory_ || name.empty())
155 return nullptr;
156 return log_writer_factory_->Create(name);
157 }
158 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
159 std::string name) {
160 if (!log_writer_factory_ || name.empty())
161 return nullptr;
162 return absl::make_unique<LogWriterFactoryAddPrefix>(
163 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200164 }
165
166 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200167 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
168
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200169 NullReceiver null_receiver_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200170 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
171 std::unique_ptr<TimeController> time_controller_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200172 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200173
174 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200175 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Artem Titov37d18482019-01-08 15:41:45 +0100176 std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200177 std::vector<std::unique_ptr<CrossTrafficSource>> cross_traffic_sources_;
178 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
179 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
180
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200181 std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
182
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200183 std::vector<std::unique_ptr<ActionReceiver>> action_receivers_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200184 std::vector<std::unique_ptr<StatesPrinter>> printers_;
185
Sebastian Jansson800e1212018-10-22 11:49:03 +0200186 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200187 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
188 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
189
190 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200191 // Defined last so it's destroyed first.
192 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200193};
194} // namespace test
195} // namespace webrtc
196
197#endif // TEST_SCENARIO_SCENARIO_H_