blob: c3fc8772899fdf615066bf1c2e4450062c2de2c5 [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 Jansson52de8b02019-01-16 17:25:44 +010020#include "test/logging/log_writer.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020021#include "test/scenario/audio_stream.h"
22#include "test/scenario/call_client.h"
23#include "test/scenario/column_printer.h"
24#include "test/scenario/network_node.h"
25#include "test/scenario/scenario_config.h"
Sebastian Jansson71a091e2018-09-27 19:08:21 +020026#include "test/scenario/simulated_time.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020027#include "test/scenario/video_stream.h"
28
29namespace webrtc {
30namespace test {
31// RepeatedActivity is created by the Scenario class and can be used to stop a
32// running activity at runtime.
33class RepeatedActivity {
34 public:
35 void Stop();
36
37 private:
38 friend class Scenario;
39 RepeatedActivity(TimeDelta interval, std::function<void(TimeDelta)> function);
40
41 void Poll(Timestamp time);
42 void SetStartTime(Timestamp time);
43 Timestamp NextTime();
44
45 TimeDelta interval_;
46 std::function<void(TimeDelta)> function_;
47 Timestamp last_update_ = Timestamp::MinusInfinity();
48};
49
50struct PendingActivity {
51 TimeDelta after_duration;
52 std::function<void()> function;
53};
54
55// Scenario is a class owning everything for a test scenario. It creates and
56// holds network nodes, call clients and media streams. It also provides methods
57// for changing behavior at runtime. Since it always keeps ownership of the
58// created components, it generally returns non-owning pointers. It maintains
59// the life of its objects until it is destroyed.
60// For methods accepting configuration structs, a modifier function interface is
61// generally provided. This allows simple partial overriding of the default
62// configuration.
63class Scenario {
64 public:
65 Scenario();
66 explicit Scenario(std::string file_name);
67 Scenario(std::string file_name, bool real_time);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010068 Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
69 bool real_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020070 RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
71 ~Scenario();
72
73 SimulationNode* CreateSimulationNode(NetworkNodeConfig config);
74 SimulationNode* CreateSimulationNode(
75 std::function<void(NetworkNodeConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +010076 EmulatedNetworkNode* CreateNetworkNode(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020077 NetworkNodeConfig config,
Artem Titov8ea1e9d2018-10-04 14:46:31 +020078 std::unique_ptr<NetworkBehaviorInterface> behavior);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020079
80 CallClient* CreateClient(std::string name, CallClientConfig config);
81 CallClient* CreateClient(
82 std::string name,
83 std::function<void(CallClientConfig*)> config_modifier);
84
Sebastian Jansson800e1212018-10-22 11:49:03 +020085 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010086 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020087 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010088 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020089
90 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010091 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020092 DataSize first_overhead,
93 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010094 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020095 DataSize second_overhead);
96
97 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010098 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020099
100 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +0100101 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +0200102 DataSize overhead);
103
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200104 SimulatedTimeClient* CreateSimulatedTimeClient(
105 std::string name,
106 SimulatedTimeClientConfig config,
107 std::vector<PacketStreamConfig> stream_configs,
Artem Titov37d18482019-01-08 15:41:45 +0100108 std::vector<EmulatedNetworkNode*> send_link,
109 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200110
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200111 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200112 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200113 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200114 VideoStreamPair* CreateVideoStream(
115 std::pair<CallClient*, CallClient*> clients,
116 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200117
118 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200119 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200120 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200121 AudioStreamPair* CreateAudioStream(
122 std::pair<CallClient*, CallClient*> clients,
123 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200124
125 CrossTrafficSource* CreateCrossTraffic(
Artem Titov37d18482019-01-08 15:41:45 +0100126 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200127 std::function<void(CrossTrafficConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +0100128 CrossTrafficSource* CreateCrossTraffic(
129 std::vector<EmulatedNetworkNode*> over_nodes,
130 CrossTrafficConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200131
132 // Runs the provided function with a fixed interval.
133 RepeatedActivity* Every(TimeDelta interval,
134 std::function<void(TimeDelta)> function);
135 RepeatedActivity* Every(TimeDelta interval, std::function<void()> function);
136
137 // Runs the provided function after given duration has passed in a session.
138 void At(TimeDelta offset, std::function<void()> function);
139
140 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100141 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200142 size_t packet_size,
143 std::function<void()> action);
144
145 // Runs the scenario for the given time or until the exit function returns
146 // true.
147 void RunFor(TimeDelta duration);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100148 void RunUntil(TimeDelta max_duration);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200149 void RunUntil(TimeDelta max_duration,
150 TimeDelta probe_interval,
151 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100152 void Start();
153 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200154
155 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100156 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200157 size_t num_packets,
158 size_t packet_size);
159
160 ColumnPrinter TimePrinter();
161 StatesPrinter* CreatePrinter(std::string name,
162 TimeDelta interval,
163 std::vector<ColumnPrinter> printers);
164
165 // Returns the current time.
166 Timestamp Now();
167 // Return the duration of the current session so far.
168 TimeDelta Duration();
169
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100170 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
171 if (!log_writer_factory_ || name.empty())
172 return nullptr;
173 return log_writer_factory_->Create(name);
174 }
175 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
176 std::string name) {
177 if (!log_writer_factory_ || name.empty())
178 return nullptr;
179 return absl::make_unique<LogWriterFactoryAddPrefix>(
180 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200181 }
182
183 private:
184 NullReceiver null_receiver_;
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100185 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200186 const bool real_time_mode_;
187 SimulatedClock sim_clock_;
188 Clock* clock_;
189 // Event logs use a global clock instance, this is used to override that
190 // instance when not running in real time.
191 rtc::FakeClock event_log_fake_clock_;
192
193 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200194 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Artem Titov37d18482019-01-08 15:41:45 +0100195 std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200196 std::vector<std::unique_ptr<CrossTrafficSource>> cross_traffic_sources_;
197 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
198 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
199
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200200 std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
201
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200202 std::vector<std::unique_ptr<RepeatedActivity>> repeated_activities_;
203 std::vector<std::unique_ptr<ActionReceiver>> action_receivers_;
204 std::vector<std::unique_ptr<PendingActivity>> pending_activities_;
205 std::vector<std::unique_ptr<StatesPrinter>> printers_;
206
Sebastian Jansson800e1212018-10-22 11:49:03 +0200207 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200208 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
209 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
210
211 Timestamp start_time_ = Timestamp::PlusInfinity();
212};
213} // namespace test
214} // namespace webrtc
215
216#endif // TEST_SCENARIO_SCENARIO_H_