xref: /aosp_15_r20/external/webrtc/test/peer_scenario/peer_scenario.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #ifndef TEST_PEER_SCENARIO_PEER_SCENARIO_H_
11*d9f75844SAndroid Build Coastguard Worker #define TEST_PEER_SCENARIO_PEER_SCENARIO_H_
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker // The peer connection scenario test framework enables writing end to end unit
14*d9f75844SAndroid Build Coastguard Worker // tests on the peer connection level. It's similar to the Scenario test but
15*d9f75844SAndroid Build Coastguard Worker // uses the full stack, including SDP and ICE negotiation. This ensures that
16*d9f75844SAndroid Build Coastguard Worker // features work end to end. It's also diffferent from the other tests on peer
17*d9f75844SAndroid Build Coastguard Worker // connection level in that it does not rely on any mocks or fakes other than
18*d9f75844SAndroid Build Coastguard Worker // for media input and networking. Additionally it provides direct access to the
19*d9f75844SAndroid Build Coastguard Worker // underlying peer connection class.
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker #include <list>
22*d9f75844SAndroid Build Coastguard Worker #include <vector>
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker #include "api/test/time_controller.h"
25*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
26*d9f75844SAndroid Build Coastguard Worker #include "test/logging/log_writer.h"
27*d9f75844SAndroid Build Coastguard Worker #include "test/network/network_emulation_manager.h"
28*d9f75844SAndroid Build Coastguard Worker #include "test/peer_scenario/peer_scenario_client.h"
29*d9f75844SAndroid Build Coastguard Worker #include "test/peer_scenario/signaling_route.h"
30*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/stats_collection.h"
31*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/video_frame_matcher.h"
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
34*d9f75844SAndroid Build Coastguard Worker namespace test {
35*d9f75844SAndroid Build Coastguard Worker // The PeerScenario class represents a PeerConnection simulation scenario. The
36*d9f75844SAndroid Build Coastguard Worker // main purpose is to maintain ownership and ensure safe destruction order of
37*d9f75844SAndroid Build Coastguard Worker // clients and network emulation. Additionally it reduces the amount of boiler
38*d9f75844SAndroid Build Coastguard Worker // plate requited for some actions. For example usage see the existing tests
39*d9f75844SAndroid Build Coastguard Worker // using this class. Note that it should be used from a single calling thread.
40*d9f75844SAndroid Build Coastguard Worker // This thread will also be assigned as the signaling thread for all peer
41*d9f75844SAndroid Build Coastguard Worker // connections that are created. This means that the process methods must be
42*d9f75844SAndroid Build Coastguard Worker // used when waiting to ensure that messages are processed on the signaling
43*d9f75844SAndroid Build Coastguard Worker // thread.
44*d9f75844SAndroid Build Coastguard Worker class PeerScenario {
45*d9f75844SAndroid Build Coastguard Worker  public:
46*d9f75844SAndroid Build Coastguard Worker   // The name is used for log output when those are enabled by the --peer_logs
47*d9f75844SAndroid Build Coastguard Worker   // command line flag. Optionally, the TestInfo struct available in gtest can
48*d9f75844SAndroid Build Coastguard Worker   // be used to automatically generate a path based on the test name.
49*d9f75844SAndroid Build Coastguard Worker   explicit PeerScenario(const testing::TestInfo& test_info,
50*d9f75844SAndroid Build Coastguard Worker                         TimeMode mode = TimeMode::kSimulated);
51*d9f75844SAndroid Build Coastguard Worker   explicit PeerScenario(std::string file_name,
52*d9f75844SAndroid Build Coastguard Worker                         TimeMode mode = TimeMode::kSimulated);
53*d9f75844SAndroid Build Coastguard Worker   explicit PeerScenario(
54*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
55*d9f75844SAndroid Build Coastguard Worker       TimeMode mode = TimeMode::kSimulated);
56*d9f75844SAndroid Build Coastguard Worker 
net()57*d9f75844SAndroid Build Coastguard Worker   NetworkEmulationManagerImpl* net() { return &net_; }
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker   // Creates a client wrapping a peer connection conforming to the given config.
60*d9f75844SAndroid Build Coastguard Worker   // The client  will share the signaling thread with the scenario. To maintain
61*d9f75844SAndroid Build Coastguard Worker   // control of destruction order, ownership is kept within the scenario.
62*d9f75844SAndroid Build Coastguard Worker   PeerScenarioClient* CreateClient(PeerScenarioClient::Config config);
63*d9f75844SAndroid Build Coastguard Worker   PeerScenarioClient* CreateClient(std::string name,
64*d9f75844SAndroid Build Coastguard Worker                                    PeerScenarioClient::Config config);
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker   // Sets up a signaling route that can be used for SDP and ICE.
67*d9f75844SAndroid Build Coastguard Worker   SignalingRoute ConnectSignaling(PeerScenarioClient* caller,
68*d9f75844SAndroid Build Coastguard Worker                                   PeerScenarioClient* callee,
69*d9f75844SAndroid Build Coastguard Worker                                   std::vector<EmulatedNetworkNode*> send_link,
70*d9f75844SAndroid Build Coastguard Worker                                   std::vector<EmulatedNetworkNode*> ret_link);
71*d9f75844SAndroid Build Coastguard Worker 
72*d9f75844SAndroid Build Coastguard Worker   // Connects two clients over given links. This will also start ICE signaling
73*d9f75844SAndroid Build Coastguard Worker   // and SDP negotiation with default behavior. For customized behavior,
74*d9f75844SAndroid Build Coastguard Worker   // ConnectSignaling should be used to allow more detailed control, for
75*d9f75844SAndroid Build Coastguard Worker   // instance to allow different signaling and media routes.
76*d9f75844SAndroid Build Coastguard Worker   void SimpleConnection(PeerScenarioClient* caller,
77*d9f75844SAndroid Build Coastguard Worker                         PeerScenarioClient* callee,
78*d9f75844SAndroid Build Coastguard Worker                         std::vector<EmulatedNetworkNode*> send_link,
79*d9f75844SAndroid Build Coastguard Worker                         std::vector<EmulatedNetworkNode*> ret_link);
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker   // Starts feeding the results of comparing captured frames from `send_track`
82*d9f75844SAndroid Build Coastguard Worker   // with decoded frames on `receiver` to `analyzer`.
83*d9f75844SAndroid Build Coastguard Worker   // TODO(srte): Provide a way to detach to allow removal of tracks.
84*d9f75844SAndroid Build Coastguard Worker   void AttachVideoQualityAnalyzer(VideoQualityAnalyzer* analyzer,
85*d9f75844SAndroid Build Coastguard Worker                                   VideoTrackInterface* send_track,
86*d9f75844SAndroid Build Coastguard Worker                                   PeerScenarioClient* receiver);
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   // Waits on `event` while processing messages on the signaling thread.
89*d9f75844SAndroid Build Coastguard Worker   bool WaitAndProcess(std::atomic<bool>* event,
90*d9f75844SAndroid Build Coastguard Worker                       TimeDelta max_duration = TimeDelta::Seconds(5));
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   // Process messages on the signaling thread for the given duration.
93*d9f75844SAndroid Build Coastguard Worker   void ProcessMessages(TimeDelta duration);
94*d9f75844SAndroid Build Coastguard Worker 
95*d9f75844SAndroid Build Coastguard Worker  private:
96*d9f75844SAndroid Build Coastguard Worker   // Helper struct to maintain ownership of the matcher and taps.
97*d9f75844SAndroid Build Coastguard Worker   struct PeerVideoQualityPair {
98*d9f75844SAndroid Build Coastguard Worker    public:
PeerVideoQualityPairPeerVideoQualityPair99*d9f75844SAndroid Build Coastguard Worker     PeerVideoQualityPair(Clock* capture_clock, VideoQualityAnalyzer* analyzer)
100*d9f75844SAndroid Build Coastguard Worker         : matcher_({analyzer->Handler()}),
101*d9f75844SAndroid Build Coastguard Worker           capture_tap_(capture_clock, &matcher_),
102*d9f75844SAndroid Build Coastguard Worker           decode_tap_(capture_clock, &matcher_, 0) {}
103*d9f75844SAndroid Build Coastguard Worker     VideoFrameMatcher matcher_;
104*d9f75844SAndroid Build Coastguard Worker     CapturedFrameTap capture_tap_;
105*d9f75844SAndroid Build Coastguard Worker     DecodedFrameTap decode_tap_;
106*d9f75844SAndroid Build Coastguard Worker   };
107*d9f75844SAndroid Build Coastguard Worker 
clock()108*d9f75844SAndroid Build Coastguard Worker   Clock* clock() { return Clock::GetRealTimeClock(); }
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
111*d9f75844SAndroid Build Coastguard Worker       std::string name);
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker   const std::unique_ptr<LogWriterFactoryInterface> log_writer_manager_;
114*d9f75844SAndroid Build Coastguard Worker   NetworkEmulationManagerImpl net_;
115*d9f75844SAndroid Build Coastguard Worker   rtc::Thread* const signaling_thread_;
116*d9f75844SAndroid Build Coastguard Worker   std::list<PeerVideoQualityPair> video_quality_pairs_;
117*d9f75844SAndroid Build Coastguard Worker   std::list<PeerScenarioClient> peer_clients_;
118*d9f75844SAndroid Build Coastguard Worker };
119*d9f75844SAndroid Build Coastguard Worker 
120*d9f75844SAndroid Build Coastguard Worker }  // namespace test
121*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
122*d9f75844SAndroid Build Coastguard Worker #endif  // TEST_PEER_SCENARIO_PEER_SCENARIO_H_
123