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