blob: 5d82a60c13e201811c3d26bce634db0d39d089af [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
Bjorn A Mellemc4f86542019-11-21 10:37:18 -080017#include "api/test/time_controller.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#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 Jansson3d4d94a2020-01-14 14:25:41 +010021#include "test/gtest.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"
30
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();
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +010044 explicit Scenario(const testing::TestInfo* test_info);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020045 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);
Artem Titov6cae2d52022-01-26 15:01:10 +000049
Sebastian Jansson98b07e92018-09-27 13:47:01 +020050 ~Scenario();
Artem Titov6cae2d52022-01-26 15:01:10 +000051
52 Scenario(const Scenario&) = delete;
53 Scenario& operator=(const Scenario&) = delete;
54
Sebastian Janssona4c22b92019-04-15 21:10:00 +020055 NetworkEmulationManagerImpl* net() { return &network_manager_; }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020056
Sebastian Janssonef86d142019-04-15 14:42:42 +020057 EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
58 EmulatedNetworkNode* CreateSimulationNode(
59 std::function<void(NetworkSimulationConfig*)> config_modifier);
60
61 SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config);
62 SimulationNode* CreateMutableSimulationNode(
63 std::function<void(NetworkSimulationConfig*)> config_modifier);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020064
65 CallClient* CreateClient(std::string name, CallClientConfig config);
66 CallClient* CreateClient(
67 std::string name,
68 std::function<void(CallClientConfig*)> config_modifier);
69
Sebastian Jansson800e1212018-10-22 11:49:03 +020070 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 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010073 std::vector<EmulatedNetworkNode*> return_link);
Sebastian Jansson800e1212018-10-22 11:49:03 +020074
75 CallClientPair* CreateRoutes(CallClient* first,
Artem Titov37d18482019-01-08 15:41:45 +010076 std::vector<EmulatedNetworkNode*> send_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020077 DataSize first_overhead,
78 CallClient* second,
Artem Titov37d18482019-01-08 15:41:45 +010079 std::vector<EmulatedNetworkNode*> return_link,
Sebastian Jansson800e1212018-10-22 11:49:03 +020080 DataSize second_overhead);
81
82 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010083 std::vector<EmulatedNetworkNode*> over_nodes);
Sebastian Jansson800e1212018-10-22 11:49:03 +020084
85 void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
Artem Titov37d18482019-01-08 15:41:45 +010086 std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson800e1212018-10-22 11:49:03 +020087 DataSize overhead);
88
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
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200103 // Runs the provided function with a fixed interval. For real time tests,
Artem Titov1ee563d2021-07-27 12:46:29 +0200104 // `function` starts being called after `interval` from the call to Every().
Sebastian Jansson123f3452019-03-13 11:22:52 +0100105 void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
106 void Every(TimeDelta interval, std::function<void()> function);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200107
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +0100108 // Runs the provided function on the internal task queue. This ensure that
109 // it's run on the main thread for simulated time tests.
110 void Post(std::function<void()> function);
111
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200112 // Runs the provided function after given duration has passed. For real time
Artem Titov1ee563d2021-07-27 12:46:29 +0200113 // tests, `function` is called after `target_time_since_start` from the call
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200114 // to Every().
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115 void At(TimeDelta offset, std::function<void()> function);
116
Artem Titov1ee563d2021-07-27 12:46:29 +0200117 // Sends a packet over the nodes and runs `action` when it has been delivered.
Artem Titov37d18482019-01-08 15:41:45 +0100118 void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200119 size_t packet_size,
120 std::function<void()> action);
121
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200122 // Runs the scenario for the given time.
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200123 void RunFor(TimeDelta duration);
Artem Titov1ee563d2021-07-27 12:46:29 +0200124 // Runs the scenario until `target_time_since_start`.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100125 void RunUntil(TimeDelta target_time_since_start);
Artem Titov1ee563d2021-07-27 12:46:29 +0200126 // Runs the scenario until `target_time_since_start` or `exit_function`
127 // returns true. `exit_function` is polled after each `check_interval` has
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200128 // passed.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100129 void RunUntil(TimeDelta target_time_since_start,
130 TimeDelta check_interval,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200131 std::function<bool()> exit_function);
Sebastian Jansson49a78432018-11-20 16:15:29 +0100132 void Start();
133 void Stop();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200134
135 // Triggers sending of dummy packets over the given nodes.
Artem Titov37d18482019-01-08 15:41:45 +0100136 void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200137 size_t num_packets,
138 size_t packet_size);
139
140 ColumnPrinter TimePrinter();
141 StatesPrinter* CreatePrinter(std::string name,
142 TimeDelta interval,
143 std::vector<ColumnPrinter> printers);
144
145 // Returns the current time.
146 Timestamp Now();
147 // Return the duration of the current session so far.
Sebastian Jansson123f3452019-03-13 11:22:52 +0100148 TimeDelta TimeSinceStart();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200149
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100150 std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
151 if (!log_writer_factory_ || name.empty())
152 return nullptr;
153 return log_writer_factory_->Create(name);
154 }
155 std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
156 std::string name) {
157 if (!log_writer_factory_ || name.empty())
158 return nullptr;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200159 return std::make_unique<LogWriterFactoryAddPrefix>(
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100160 log_writer_factory_.get(), name);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200161 }
162
163 private:
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200164 TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
165
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200166 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100167 NetworkEmulationManagerImpl network_manager_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200168 Clock* clock_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200169
170 std::vector<std::unique_ptr<CallClient>> clients_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200171 std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200172 std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
173 std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
Sebastian Janssona4c22b92019-04-15 21:10:00 +0200174 std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200175 std::vector<std::unique_ptr<StatesPrinter>> printers_;
176
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200177 rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
178 rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
179
180 Timestamp start_time_ = Timestamp::PlusInfinity();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200181 // Defined last so it's destroyed first.
182 rtc::TaskQueue task_queue_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200183};
184} // namespace test
185} // namespace webrtc
186
187#endif // TEST_SCENARIO_SCENARIO_H_