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