blob: 519c3828eb45ff64d3f1f9cbb1a3de65ff3dfac5 [file] [log] [blame]
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "test/peer_scenario/peer_scenario.h"
#include "absl/flags/flag.h"
#include "absl/memory/memory.h"
#include "rtc_base/null_socket_server.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/strings/string_builder.h"
#include "test/logging/file_log_writer.h"
#include "test/network/network_emulation_manager.h"
#include "test/testsupport/file_utils.h"
#include "test/time_controller/real_time_controller.h"
#include "test/time_controller/simulated_time_controller.h"
ABSL_FLAG(bool, peer_logs, false, "Save logs from peer scenario framework.");
ABSL_FLAG(std::string,
peer_logs_root,
"",
"Output root path, based on project root if unset.");
namespace webrtc {
namespace test {
namespace {
std::unique_ptr<FileLogWriterFactory> GetPeerScenarioLogManager(
std::string file_name) {
if (absl::GetFlag(FLAGS_peer_logs) && !file_name.empty()) {
std::string output_root = absl::GetFlag(FLAGS_peer_logs_root);
if (output_root.empty())
output_root = OutputPath() + "output_data/";
auto base_filename = output_root + file_name + ".";
RTC_LOG(LS_INFO) << "Saving peer scenario logs to: " << base_filename;
return std::make_unique<FileLogWriterFactory>(base_filename);
}
return nullptr;
}
} // namespace
PeerScenario::PeerScenario(const testing::TestInfo& test_info, TimeMode mode)
: PeerScenario(
std::string(test_info.test_suite_name()) + "/" + test_info.name(),
mode) {}
PeerScenario::PeerScenario(std::string file_name, TimeMode mode)
: PeerScenario(GetPeerScenarioLogManager(file_name), mode) {}
PeerScenario::PeerScenario(
std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
TimeMode mode)
: log_writer_manager_(std::move(log_writer_manager)),
net_({.time_mode = mode}),
signaling_thread_(net_.time_controller()->GetMainThread()) {}
PeerScenarioClient* PeerScenario::CreateClient(
PeerScenarioClient::Config config) {
return CreateClient(
std::string("client_") + rtc::ToString(peer_clients_.size() + 1), config);
}
PeerScenarioClient* PeerScenario::CreateClient(
std::string name,
PeerScenarioClient::Config config) {
peer_clients_.emplace_back(net(), signaling_thread_,
GetLogWriterFactory(name), config);
return &peer_clients_.back();
}
SignalingRoute PeerScenario::ConnectSignaling(
PeerScenarioClient* caller,
PeerScenarioClient* callee,
std::vector<EmulatedNetworkNode*> send_link,
std::vector<EmulatedNetworkNode*> ret_link) {
return SignalingRoute(caller, callee, net_.CreateCrossTrafficRoute(send_link),
net_.CreateCrossTrafficRoute(ret_link));
}
void PeerScenario::SimpleConnection(
PeerScenarioClient* caller,
PeerScenarioClient* callee,
std::vector<EmulatedNetworkNode*> send_link,
std::vector<EmulatedNetworkNode*> ret_link) {
net()->CreateRoute(caller->endpoint(), send_link, callee->endpoint());
net()->CreateRoute(callee->endpoint(), ret_link, caller->endpoint());
auto signaling = ConnectSignaling(caller, callee, send_link, ret_link);
signaling.StartIceSignaling();
std::atomic<bool> done(false);
signaling.NegotiateSdp(
[&](const SessionDescriptionInterface&) { done = true; });
RTC_CHECK(WaitAndProcess(&done));
}
void PeerScenario::AttachVideoQualityAnalyzer(VideoQualityAnalyzer* analyzer,
VideoTrackInterface* send_track,
PeerScenarioClient* receiver) {
video_quality_pairs_.emplace_back(clock(), analyzer);
auto pair = &video_quality_pairs_.back();
send_track->AddOrUpdateSink(&pair->capture_tap_, rtc::VideoSinkWants());
receiver->AddVideoReceiveSink(send_track->id(), &pair->decode_tap_);
}
bool PeerScenario::WaitAndProcess(std::atomic<bool>* event,
TimeDelta max_duration) {
return net_.time_controller()->Wait([event] { return event->load(); },
max_duration);
}
void PeerScenario::ProcessMessages(TimeDelta duration) {
net_.time_controller()->AdvanceTime(duration);
}
std::unique_ptr<LogWriterFactoryInterface> PeerScenario::GetLogWriterFactory(
std::string name) {
if (!log_writer_manager_ || name.empty())
return nullptr;
return std::make_unique<LogWriterFactoryAddPrefix>(log_writer_manager_.get(),
name);
}
} // namespace test
} // namespace webrtc