blob: f566840d6950f571fe51e9a13d77027af72cafd4 [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
Steve Anton10542f22019-01-11 09:11:00 -080017#include "rtc_base/constructor_magic.h"
18#include "rtc_base/fake_clock.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020019#include "test/scenario/audio_stream.h"
20#include "test/scenario/call_client.h"
21#include "test/scenario/column_printer.h"
22#include "test/scenario/network_node.h"
23#include "test/scenario/scenario_config.h"
Sebastian Jansson71a091e2018-09-27 19:08:21 +020024#include "test/scenario/simulated_time.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020025#include "test/scenario/video_stream.h"
26
27namespace webrtc {
28namespace test {
29// RepeatedActivity is created by the Scenario class and can be used to stop a
30// running activity at runtime.
31class RepeatedActivity {
32 public:
33 void Stop();
34
35 private:
36 friend class Scenario;
37 RepeatedActivity(TimeDelta interval, std::function<void(TimeDelta)> function);
38
39 void Poll(Timestamp time);
40 void SetStartTime(Timestamp time);
41 Timestamp NextTime();
42
43 TimeDelta interval_;
44 std::function<void(TimeDelta)> function_;
45 Timestamp last_update_ = Timestamp::MinusInfinity();
46};
47
48struct PendingActivity {
49 TimeDelta after_duration;
50 std::function<void()> function;
51};
52
53// Scenario is a class owning everything for a test scenario. It creates and
54// holds network nodes, call clients and media streams. It also provides methods
55// for changing behavior at runtime. Since it always keeps ownership of the
56// created components, it generally returns non-owning pointers. It maintains
57// the life of its objects until it is destroyed.
58// For methods accepting configuration structs, a modifier function interface is
59// generally provided. This allows simple partial overriding of the default
60// configuration.
61class Scenario {
62 public:
63 Scenario();
64 explicit Scenario(std::string file_name);
65 Scenario(std::string file_name, bool real_time);
66 RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
67 ~Scenario();
68
69 SimulationNode* CreateSimulationNode(NetworkNodeConfig config);
70 SimulationNode* CreateSimulationNode(
71 std::function<void(NetworkNodeConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +010072 EmulatedNetworkNode* CreateNetworkNode(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020073 NetworkNodeConfig config,
Artem Titov8ea1e9d2018-10-04 14:46:31 +020074 std::unique_ptr<NetworkBehaviorInterface> behavior);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020075
76 CallClient* CreateClient(std::string name, CallClientConfig config);
77 CallClient* CreateClient(
78 std::string name,
79 std::function<void(CallClientConfig*)> config_modifier);
80
Sebastian Jansson800e1212018-10-22 11:49:03 +020081 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010082 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020083 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010084 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020085
86 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010087 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020088 DataSize first_overhead,
89 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010090 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020091 DataSize second_overhead);
92
93 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010094 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020095
96 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010097 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020098 DataSize overhead);
99
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200100 SimulatedTimeClient* CreateSimulatedTimeClient(
101 std::string name,
102 SimulatedTimeClientConfig config,
103 std::vector<PacketStreamConfig> stream_configs,
Artem Titov37d18482019-01-08 15:41:45 +0100104 std::vector<EmulatedNetworkNode*> send_link,
105 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200106
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200107 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200108 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200109 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200110 VideoStreamPair* CreateVideoStream(
111 std::pair<CallClient*, CallClient*> clients,
112 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200113
114 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200115 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200116 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200117 AudioStreamPair* CreateAudioStream(
118 std::pair<CallClient*, CallClient*> clients,
119 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200120
121 CrossTrafficSource* CreateCrossTraffic(
Artem Titov37d18482019-01-08 15:41:45 +0100122 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200123 std::function<void(CrossTrafficConfig*)> config_modifier);
Artem Titov37d18482019-01-08 15:41:45 +0100124 CrossTrafficSource* CreateCrossTraffic(
125 std::vector<EmulatedNetworkNode*> over_nodes,
126 CrossTrafficConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200127
128 // Runs the provided function with a fixed interval.
129 RepeatedActivity* Every(TimeDelta interval,
130 std::function<void(TimeDelta)> function);
131 RepeatedActivity* Every(TimeDelta interval, std::function<void()> function);
132
133 // Runs the provided function after given duration has passed in a session.
134 void At(TimeDelta offset, std::function<void()> function);
135
136 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100137 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200138 size_t packet_size,
139 std::function<void()> action);
140
141 // Runs the scenario for the given time or until the exit function returns
142 // true.
143 void RunFor(TimeDelta duration);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100144 void RunUntil(TimeDelta max_duration);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200145 void RunUntil(TimeDelta max_duration,
146 TimeDelta probe_interval,
147 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100148 void Start();
149 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200150
151 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100152 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200153 size_t num_packets,
154 size_t packet_size);
155
156 ColumnPrinter TimePrinter();
157 StatesPrinter* CreatePrinter(std::string name,
158 TimeDelta interval,
159 std::vector<ColumnPrinter> printers);
160
161 // Returns the current time.
162 Timestamp Now();
163 // Return the duration of the current session so far.
164 TimeDelta Duration();
165
166 std::string GetFullPathOrEmpty(std::string name) const {
167 if (base_filename_.empty() || name.empty())
168 return std::string();
169 return base_filename_ + "." + name;
170 }
171
172 private:
173 NullReceiver null_receiver_;
174 std::string base_filename_;
175 const bool real_time_mode_;
176 SimulatedClock sim_clock_;
177 Clock* clock_;
178 // Event logs use a global clock instance, this is used to override that
179 // instance when not running in real time.
180 rtc::FakeClock event_log_fake_clock_;
181
182 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200183 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Artem Titov37d18482019-01-08 15:41:45 +0100184 std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200185 std::vector<std::unique_ptr<CrossTrafficSource>> cross_traffic_sources_;
186 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
187 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
188
Sebastian Jansson71a091e2018-09-27 19:08:21 +0200189 std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
190
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200191 std::vector<std::unique_ptr<RepeatedActivity>> repeated_activities_;
192 std::vector<std::unique_ptr<ActionReceiver>> action_receivers_;
193 std::vector<std::unique_ptr<PendingActivity>> pending_activities_;
194 std::vector<std::unique_ptr<StatesPrinter>> printers_;
195
Sebastian Jansson800e1212018-10-22 11:49:03 +0200196 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200197 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
198 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
199
200 Timestamp start_time_ = Timestamp::PlusInfinity();
201};
202} // namespace test
203} // namespace webrtc
204
205#endif // TEST_SCENARIO_SCENARIO_H_