• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "api/test/time_controller.h"
18 #include "rtc_base/constructor_magic.h"
19 #include "rtc_base/fake_clock.h"
20 #include "rtc_base/task_queue.h"
21 #include "rtc_base/task_utils/repeating_task.h"
22 #include "test/gtest.h"
23 #include "test/logging/log_writer.h"
24 #include "test/network/network_emulation_manager.h"
25 #include "test/scenario/audio_stream.h"
26 #include "test/scenario/call_client.h"
27 #include "test/scenario/column_printer.h"
28 #include "test/scenario/network_node.h"
29 #include "test/scenario/scenario_config.h"
30 #include "test/scenario/video_stream.h"
31 
32 namespace webrtc {
33 namespace test {
34 // 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.
42 class Scenario {
43  public:
44   Scenario();
45   explicit Scenario(const testing::TestInfo* test_info);
46   explicit Scenario(std::string file_name);
47   Scenario(std::string file_name, bool real_time);
48   Scenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
49            bool real_time);
50   RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
51   ~Scenario();
net()52   NetworkEmulationManagerImpl* net() { return &network_manager_; }
53 
54   EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
55   EmulatedNetworkNode* CreateSimulationNode(
56       std::function<void(NetworkSimulationConfig*)> config_modifier);
57 
58   SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config);
59   SimulationNode* CreateMutableSimulationNode(
60       std::function<void(NetworkSimulationConfig*)> config_modifier);
61 
62   CallClient* CreateClient(std::string name, CallClientConfig config);
63   CallClient* CreateClient(
64       std::string name,
65       std::function<void(CallClientConfig*)> config_modifier);
66 
67   CallClientPair* CreateRoutes(CallClient* first,
68                                std::vector<EmulatedNetworkNode*> send_link,
69                                CallClient* second,
70                                std::vector<EmulatedNetworkNode*> return_link);
71 
72   CallClientPair* CreateRoutes(CallClient* first,
73                                std::vector<EmulatedNetworkNode*> send_link,
74                                DataSize first_overhead,
75                                CallClient* second,
76                                std::vector<EmulatedNetworkNode*> return_link,
77                                DataSize second_overhead);
78 
79   void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
80                    std::vector<EmulatedNetworkNode*> over_nodes);
81 
82   void ChangeRoute(std::pair<CallClient*, CallClient*> clients,
83                    std::vector<EmulatedNetworkNode*> over_nodes,
84                    DataSize overhead);
85 
86   VideoStreamPair* CreateVideoStream(
87       std::pair<CallClient*, CallClient*> clients,
88       std::function<void(VideoStreamConfig*)> config_modifier);
89   VideoStreamPair* CreateVideoStream(
90       std::pair<CallClient*, CallClient*> clients,
91       VideoStreamConfig config);
92 
93   AudioStreamPair* CreateAudioStream(
94       std::pair<CallClient*, CallClient*> clients,
95       std::function<void(AudioStreamConfig*)> config_modifier);
96   AudioStreamPair* CreateAudioStream(
97       std::pair<CallClient*, CallClient*> clients,
98       AudioStreamConfig config);
99 
100   // Runs the provided function with a fixed interval. For real time tests,
101   // |function| starts being called after |interval| from the call to Every().
102   void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
103   void Every(TimeDelta interval, std::function<void()> function);
104 
105   // Runs the provided function on the internal task queue. This ensure that
106   // it's run on the main thread for simulated time tests.
107   void Post(std::function<void()> function);
108 
109   // Runs the provided function after given duration has passed. For real time
110   // tests, |function| is called after |target_time_since_start| from the call
111   // to Every().
112   void At(TimeDelta offset, std::function<void()> function);
113 
114   // Sends a packet over the nodes and runs |action| when it has been delivered.
115   void NetworkDelayedAction(std::vector<EmulatedNetworkNode*> over_nodes,
116                             size_t packet_size,
117                             std::function<void()> action);
118 
119   // Runs the scenario for the given time.
120   void RunFor(TimeDelta duration);
121   // Runs the scenario until |target_time_since_start|.
122   void RunUntil(TimeDelta target_time_since_start);
123   // Runs the scenario until |target_time_since_start| or |exit_function|
124   // returns true. |exit_function| is polled after each |check_interval| has
125   // passed.
126   void RunUntil(TimeDelta target_time_since_start,
127                 TimeDelta check_interval,
128                 std::function<bool()> exit_function);
129   void Start();
130   void Stop();
131 
132   // Triggers sending of dummy packets over the given nodes.
133   void TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
134                           size_t num_packets,
135                           size_t packet_size);
136 
137   ColumnPrinter TimePrinter();
138   StatesPrinter* CreatePrinter(std::string name,
139                                TimeDelta interval,
140                                std::vector<ColumnPrinter> printers);
141 
142   // Returns the current time.
143   Timestamp Now();
144   // Return the duration of the current session so far.
145   TimeDelta TimeSinceStart();
146 
GetLogWriter(std::string name)147   std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name) {
148     if (!log_writer_factory_ || name.empty())
149       return nullptr;
150     return log_writer_factory_->Create(name);
151   }
GetLogWriterFactory(std::string name)152   std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
153       std::string name) {
154     if (!log_writer_factory_ || name.empty())
155       return nullptr;
156     return std::make_unique<LogWriterFactoryAddPrefix>(
157         log_writer_factory_.get(), name);
158   }
159 
160  private:
161   TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
162 
163   const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
164   NetworkEmulationManagerImpl network_manager_;
165   Clock* clock_;
166 
167   std::vector<std::unique_ptr<CallClient>> clients_;
168   std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
169   std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
170   std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
171   std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
172   std::vector<std::unique_ptr<StatesPrinter>> printers_;
173 
174   rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
175   rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
176 
177   Timestamp start_time_ = Timestamp::PlusInfinity();
178   // Defined last so it's destroyed first.
179   rtc::TaskQueue task_queue_;
180 };
181 }  // namespace test
182 }  // namespace webrtc
183 
184 #endif  // TEST_SCENARIO_SCENARIO_H_
185