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