peer_scenario.h 5.6 KB

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