• 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 #include "test/peer_scenario/peer_scenario.h"
11 
12 #include "absl/flags/flag.h"
13 #include "absl/memory/memory.h"
14 #include "rtc_base/null_socket_server.h"
15 #include "rtc_base/string_encode.h"
16 #include "rtc_base/strings/string_builder.h"
17 #include "test/logging/file_log_writer.h"
18 #include "test/testsupport/file_utils.h"
19 #include "test/time_controller/real_time_controller.h"
20 #include "test/time_controller/simulated_time_controller.h"
21 
22 ABSL_FLAG(bool, peer_logs, false, "Save logs from peer scenario framework.");
23 ABSL_FLAG(std::string,
24           peer_logs_root,
25           "",
26           "Output root path, based on project root if unset.");
27 
28 namespace webrtc {
29 namespace test {
30 namespace {
GetPeerScenarioLogManager(std::string file_name)31 std::unique_ptr<FileLogWriterFactory> GetPeerScenarioLogManager(
32     std::string file_name) {
33   if (absl::GetFlag(FLAGS_peer_logs) && !file_name.empty()) {
34     std::string output_root = absl::GetFlag(FLAGS_peer_logs_root);
35     if (output_root.empty())
36       output_root = OutputPath() + "output_data/";
37 
38     auto base_filename = output_root + file_name + ".";
39     RTC_LOG(LS_INFO) << "Saving peer scenario logs to: " << base_filename;
40     return std::make_unique<FileLogWriterFactory>(base_filename);
41   }
42   return nullptr;
43 }
44 }  // namespace
45 
PeerScenario(const testing::TestInfo & test_info,TimeMode mode)46 PeerScenario::PeerScenario(const testing::TestInfo& test_info, TimeMode mode)
47     : PeerScenario(
48           std::string(test_info.test_suite_name()) + "/" + test_info.name(),
49           mode) {}
50 
PeerScenario(std::string file_name,TimeMode mode)51 PeerScenario::PeerScenario(std::string file_name, TimeMode mode)
52     : PeerScenario(GetPeerScenarioLogManager(file_name), mode) {}
53 
PeerScenario(std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,TimeMode mode)54 PeerScenario::PeerScenario(
55     std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
56     TimeMode mode)
57     : log_writer_manager_(std::move(log_writer_manager)),
58       net_(mode),
59       signaling_thread_(net_.time_controller()->GetMainThread()) {}
60 
CreateClient(PeerScenarioClient::Config config)61 PeerScenarioClient* PeerScenario::CreateClient(
62     PeerScenarioClient::Config config) {
63   return CreateClient(
64       std::string("client_") + rtc::ToString(peer_clients_.size() + 1), config);
65 }
66 
CreateClient(std::string name,PeerScenarioClient::Config config)67 PeerScenarioClient* PeerScenario::CreateClient(
68     std::string name,
69     PeerScenarioClient::Config config) {
70   peer_clients_.emplace_back(net(), signaling_thread_,
71                              GetLogWriterFactory(name), config);
72   return &peer_clients_.back();
73 }
74 
ConnectSignaling(PeerScenarioClient * caller,PeerScenarioClient * callee,std::vector<EmulatedNetworkNode * > send_link,std::vector<EmulatedNetworkNode * > ret_link)75 SignalingRoute PeerScenario::ConnectSignaling(
76     PeerScenarioClient* caller,
77     PeerScenarioClient* callee,
78     std::vector<EmulatedNetworkNode*> send_link,
79     std::vector<EmulatedNetworkNode*> ret_link) {
80   return SignalingRoute(caller, callee, net_.CreateTrafficRoute(send_link),
81                         net_.CreateTrafficRoute(ret_link));
82 }
83 
SimpleConnection(PeerScenarioClient * caller,PeerScenarioClient * callee,std::vector<EmulatedNetworkNode * > send_link,std::vector<EmulatedNetworkNode * > ret_link)84 void PeerScenario::SimpleConnection(
85     PeerScenarioClient* caller,
86     PeerScenarioClient* callee,
87     std::vector<EmulatedNetworkNode*> send_link,
88     std::vector<EmulatedNetworkNode*> ret_link) {
89   net()->CreateRoute(caller->endpoint(), send_link, callee->endpoint());
90   net()->CreateRoute(callee->endpoint(), ret_link, caller->endpoint());
91   auto signaling = ConnectSignaling(caller, callee, send_link, ret_link);
92   signaling.StartIceSignaling();
93   std::atomic<bool> done(false);
94   signaling.NegotiateSdp(
95       [&](const SessionDescriptionInterface&) { done = true; });
96   RTC_CHECK(WaitAndProcess(&done));
97 }
98 
AttachVideoQualityAnalyzer(VideoQualityAnalyzer * analyzer,VideoTrackInterface * send_track,PeerScenarioClient * receiver)99 void PeerScenario::AttachVideoQualityAnalyzer(VideoQualityAnalyzer* analyzer,
100                                               VideoTrackInterface* send_track,
101                                               PeerScenarioClient* receiver) {
102   video_quality_pairs_.emplace_back(clock(), analyzer);
103   auto pair = &video_quality_pairs_.back();
104   send_track->AddOrUpdateSink(&pair->capture_tap_, rtc::VideoSinkWants());
105   receiver->AddVideoReceiveSink(send_track->id(), &pair->decode_tap_);
106 }
107 
WaitAndProcess(std::atomic<bool> * event,TimeDelta max_duration)108 bool PeerScenario::WaitAndProcess(std::atomic<bool>* event,
109                                   TimeDelta max_duration) {
110   return net_.time_controller()->Wait([event] { return event->load(); },
111                                       max_duration);
112 }
113 
ProcessMessages(TimeDelta duration)114 void PeerScenario::ProcessMessages(TimeDelta duration) {
115   net_.time_controller()->AdvanceTime(duration);
116 }
117 
GetLogWriterFactory(std::string name)118 std::unique_ptr<LogWriterFactoryInterface> PeerScenario::GetLogWriterFactory(
119     std::string name) {
120   if (!log_writer_manager_ || name.empty())
121     return nullptr;
122   return std::make_unique<LogWriterFactoryAddPrefix>(log_writer_manager_.get(),
123                                                      name);
124 }
125 
126 }  // namespace test
127 }  // namespace webrtc
128