blob: fc4fcedb101ac04d52b80be939ba6b6ad507cfd8 [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"
Artem Titov386802e2019-07-05 10:48:17 +020023#include "test/network/network_emulation_manager.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020024#include "test/scenario/audio_stream.h"
25#include "test/scenario/call_client.h"
26#include "test/scenario/column_printer.h"
27#include "test/scenario/network_node.h"
28#include "test/scenario/scenario_config.h"
29#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();
Sebastian Janssona4c22b92019-04-15 21:10:00 +020051 NetworkEmulationManagerImpl* net() { return &network_manager_; }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020052
Sebastian Janssonef86d142019-04-15 14:42:42 +020053 EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
54 EmulatedNetworkNode* CreateSimulationNode(
55 std::function<void(NetworkSimulationConfig*)> config_modifier);
56
57 SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config);
58 SimulationNode* CreateMutableSimulationNode(
59 std::function<void(NetworkSimulationConfig*)> config_modifier);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020060
61 CallClient* CreateClient(std::string name, CallClientConfig config);
62 CallClient* CreateClient(
63 std::string name,
64 std::function<void(CallClientConfig*)> config_modifier);
65
Sebastian Jansson800e1212018-10-22 11:49:03 +020066 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010067 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020068 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010069 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020070
71 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010072 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020073 DataSize first_overhead,
74 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010075 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020076 DataSize second_overhead);
77
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
81 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010082 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020083 DataSize overhead);
84
Sebastian Jansson98b07e92018-09-27 13:47:01 +020085 VideoStreamPair* CreateVideoStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020086 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020087 std::function<void(VideoStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020088 VideoStreamPair* CreateVideoStream(
89 std::pair<CallClient*, CallClient*> clients,
90 VideoStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020091
92 AudioStreamPair* CreateAudioStream(
Sebastian Jansson800e1212018-10-22 11:49:03 +020093 std::pair<CallClient*, CallClient*> clients,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020094 std::function<void(AudioStreamConfig*)> config_modifier);
Sebastian Jansson800e1212018-10-22 11:49:03 +020095 AudioStreamPair* CreateAudioStream(
96 std::pair<CallClient*, CallClient*> clients,
97 AudioStreamConfig config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020098
Sebastian Jansson105a10a2019-04-01 09:18:14 +020099 // Runs the provided function with a fixed interval. For real time tests,
100 // |function| starts being called after |interval| from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100101 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
102 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200103
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200104 // Runs the provided function after given duration has passed. For real time
105 // tests, |function| is called after |target_time_since_start| from the call
106 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200107 void At(TimeDelta offset, std::function<void()> function);
108
109 // Sends a packet over the nodes and runs |action| when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100110 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200111 size_t packet_size,
112 std::function<void()> action);
113
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200114 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115 void RunFor(TimeDelta duration);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200116 // Runs the scenario until |target_time_since_start|.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100117 void RunUntil(TimeDelta target_time_since_start);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200118 // Runs the scenario until |target_time_since_start| or |exit_function|
119 // returns true. |exit_function| is polled after each |check_interval| has
120 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100121 void RunUntil(TimeDelta target_time_since_start,
122 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200123 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100124 void Start();
125 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200126
127 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100128 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200129 size_t num_packets,
130 size_t packet_size);
131
132 ColumnPrinter TimePrinter();
133 StatesPrinter* CreatePrinter(std::string name,
134 TimeDelta interval,
135 std::vector<ColumnPrinter> printers);
136
137 // Returns the current time.
138 Timestamp Now();
139 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100140 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200141
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100142 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
143 if (!log_writer_factory_ || name.empty())
144 return nullptr;
145 return log_writer_factory_->Create(name);
146 }
147 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
148 std::string name) {
149 if (!log_writer_factory_ || name.empty())
150 return nullptr;
151 return absl::make_unique<LogWriterFactoryAddPrefix>(
152 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200153 }
154
155 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200156 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
157
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200158 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
159 std::unique_ptr<TimeController> time_controller_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200160 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200161
162 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200163 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200164 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
165 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200166 std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200167 std::vector<std::unique_ptr<StatesPrinter>> printers_;
168
Sebastian Jansson800e1212018-10-22 11:49:03 +0200169 int64_t next_route_id_ = 40000;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200170 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
171 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
172
173 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200174 NetworkEmulationManagerImpl network_manager_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200175 // Defined last so it's destroyed first.
176 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200177};
178} // namespace test
179} // namespace webrtc
180
181#endif // TEST_SCENARIO_SCENARIO_H_