blob: 33cf029715c2b6facdb131251f1dd04902b81f15 [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 Jansson105a10a2019-04-01 09:18:14 +020019#include "rtc_base/task_queue.h"
20#include "rtc_base/task_utils/repeating_task.h"
Sebastian Jansson52de8b02019-01-16 17:25:44 +010021#include "test/logging/log_writer.h"
Artem Titov386802e2019-07-05 10:48:17 +020022#include "test/network/network_emulation_manager.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"
28#include "test/scenario/video_stream.h"
Sebastian Jansson105a10a2019-04-01 09:18:14 +020029#include "test/time_controller/time_controller.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020030
31namespace webrtc {
32namespace test {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020033// Scenario is a class owning everything for a test scenario. It creates and
34// holds network nodes, call clients and media streams. It also provides methods
35// for changing behavior at runtime. Since it always keeps ownership of the
36// created components, it generally returns non-owning pointers. It maintains
37// the life of its objects until it is destroyed.
38// For methods accepting configuration structs, a modifier function interface is
39// generally provided. This allows simple partial overriding of the default
40// configuration.
41class Scenario {
42 public:
43 Scenario();
44 explicit Scenario(std::string file_name);
45 Scenario(std::string file_name, bool real_time);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010046 Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
47 bool real_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020048 RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
49 ~Scenario();
Sebastian Janssona4c22b92019-04-15 21:10:00 +020050 NetworkEmulationManagerImpl* net() { return &network_manager_; }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020051
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 Jansson98b07e92018-09-27 13:47:01 +020084 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020085 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020086 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020087 VideoStreamPair* CreateVideoStream(
88 std::pair<CallClient*, CallClient*> clients,
89 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020090
91 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020092 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020093 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020094 AudioStreamPair* CreateAudioStream(
95 std::pair<CallClient*, CallClient*> clients,
96 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020097
Sebastian Jansson105a10a2019-04-01 09:18:14 +020098 // Runs the provided function with a fixed interval. For real time tests,
99 // |function| starts being called after |interval| from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100100 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
101 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200102
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200103 // Runs the provided function after given duration has passed. For real time
104 // tests, |function| is called after |target_time_since_start| from the call
105 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200106 void At(TimeDelta offset, std::function<void()> function);
107
108 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100109 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200110 size_t packet_size,
111 std::function<void()> action);
112
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200113 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200114 void RunFor(TimeDelta duration);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200115 // Runs the scenario until |target_time_since_start|.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100116 void RunUntil(TimeDelta target_time_since_start);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200117 // Runs the scenario until |target_time_since_start| or |exit_function|
118 // returns true. |exit_function| is polled after each |check_interval| has
119 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100120 void RunUntil(TimeDelta target_time_since_start,
121 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200122 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100123 void Start();
124 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200125
126 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100127 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200128 size_t num_packets,
129 size_t packet_size);
130
131 ColumnPrinter TimePrinter();
132 StatesPrinter* CreatePrinter(std::string name,
133 TimeDelta interval,
134 std::vector<ColumnPrinter> printers);
135
136 // Returns the current time.
137 Timestamp Now();
138 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100139 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200140
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100141 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
142 if (!log_writer_factory_ || name.empty())
143 return nullptr;
144 return log_writer_factory_->Create(name);
145 }
146 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
147 std::string name) {
148 if (!log_writer_factory_ || name.empty())
149 return nullptr;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200150 return std::make_unique<LogWriterFactoryAddPrefix>(
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100151 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200152 }
153
154 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200155 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
156
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200157 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
158 std::unique_ptr<TimeController> time_controller_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200159 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200160
161 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200162 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200163 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
164 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200165 std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200166 std::vector<std::unique_ptr<StatesPrinter>> printers_;
167
Sebastian Jansson800e1212018-10-22 11:49:03 +0200168 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200169 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
170 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
171
172 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200173 NetworkEmulationManagerImpl network_manager_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200174 // Defined last so it's destroyed first.
175 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200176};
177} // namespace test
178} // namespace webrtc
179
180#endif // TEST_SCENARIO_SCENARIO_H_