From 64672dce41747af5ebe2f3a2f2157b9650783cf4 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Tue, 1 Oct 2019 15:23:39 +0200 Subject: [PATCH] Adds log output to peer connection level scenario framework. Based on similar code in the call level scenario test framework. Bug: webrtc:10839 Change-Id: I262a890aa2cf905bb81b0f07957c08d0df5f7651 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154745 Commit-Queue: Sebastian Jansson Reviewed-by: Jonas Olsson Cr-Commit-Position: refs/heads/master@{#29361} --- test/peer_scenario/BUILD.gn | 5 ++ test/peer_scenario/peer_scenario.cc | 56 ++++++++++++++++++- test/peer_scenario/peer_scenario.h | 19 ++++++- test/peer_scenario/peer_scenario_client.cc | 13 ++++- test/peer_scenario/peer_scenario_client.h | 11 ++-- .../tests/peer_scenario_quality_test.cc | 2 +- .../tests/remote_estimate_test.cc | 4 +- 7 files changed, 96 insertions(+), 14 deletions(-) diff --git a/test/peer_scenario/BUILD.gn b/test/peer_scenario/BUILD.gn index e35a24468e..03bb1d6711 100644 --- a/test/peer_scenario/BUILD.gn +++ b/test/peer_scenario/BUILD.gn @@ -24,6 +24,8 @@ if (rtc_include_tests) { "signaling_route.h", ] deps = [ + "..:fileutils", + "..:test_support", "../:video_test_common", "../../api:libjingle_peerconnection_api", "../../api:network_emulation_manager_api", @@ -41,8 +43,11 @@ if (rtc_include_tests) { "../../p2p:rtc_p2p", "../../pc:pc_test_utils", "../../pc:rtc_pc_base", + "../../rtc_base:stringutils", "..//network:emulated_network", + "../logging:log_writer", "../scenario", + "//third_party/abseil-cpp/absl/flags:flag", "//third_party/abseil-cpp/absl/memory", ] } diff --git a/test/peer_scenario/peer_scenario.cc b/test/peer_scenario/peer_scenario.cc index fae3c78677..ddc4b5ba87 100644 --- a/test/peer_scenario/peer_scenario.cc +++ b/test/peer_scenario/peer_scenario.cc @@ -9,16 +9,60 @@ */ #include "test/peer_scenario/peer_scenario.h" +#include "absl/flags/flag.h" #include "absl/memory/memory.h" +#include "rtc_base/string_encode.h" +#include "rtc_base/strings/string_builder.h" +#include "test/logging/file_log_writer.h" +#include "test/testsupport/file_utils.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 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/"; -PeerScenario::PeerScenario() : signaling_thread_(rtc::Thread::Current()) {} + auto base_filename = output_root + file_name + "."; + RTC_LOG(LS_INFO) << "Saving peer scenario logs to: " << base_filename; + return std::make_unique(base_filename); + } + return nullptr; +} +} // namespace + +PeerScenario::PeerScenario(const testing::TestInfo& test_info) + : PeerScenario(std::string(test_info.test_suite_name()) + "/" + + test_info.name()) {} + +PeerScenario::PeerScenario(std::string file_name) + : PeerScenario(GetPeerScenarioLogManager(file_name)) {} + +PeerScenario::PeerScenario( + std::unique_ptr log_writer_manager) + : signaling_thread_(rtc::Thread::Current()), + log_writer_manager_(std::move(log_writer_manager)) {} PeerScenarioClient* PeerScenario::CreateClient( PeerScenarioClient::Config config) { - peer_clients_.emplace_back(net(), thread(), 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(), thread(), GetLogWriterFactory(name), + config); return &peer_clients_.back(); } @@ -71,5 +115,13 @@ void PeerScenario::ProcessMessages(TimeDelta duration) { thread()->ProcessMessages(duration.ms()); } +std::unique_ptr PeerScenario::GetLogWriterFactory( + std::string name) { + if (!log_writer_manager_ || name.empty()) + return nullptr; + return std::make_unique(log_writer_manager_.get(), + name); +} + } // namespace test } // namespace webrtc diff --git a/test/peer_scenario/peer_scenario.h b/test/peer_scenario/peer_scenario.h index f945fb46fa..8040f5d2fd 100644 --- a/test/peer_scenario/peer_scenario.h +++ b/test/peer_scenario/peer_scenario.h @@ -21,6 +21,8 @@ #include #include +#include "test/gtest.h" +#include "test/logging/log_writer.h" #include "test/network/network_emulation_manager.h" #include "test/peer_scenario/peer_scenario_client.h" #include "test/peer_scenario/signaling_route.h" @@ -32,7 +34,7 @@ namespace test { // The PeerScenario class represents a PeerConnection simulation scenario. The // main purpose is to maintain ownership and ensure safe destruction order of -// clients and network emulation. Additionally it reduces the amount of bolier +// clients and network emulation. Additionally it reduces the amount of boiler // plate requited for some actions. For example usage see the existing tests // using this class. Note that it should be used from a single calling thread. // This thread will also be assigned as the signaling thread for all peer @@ -41,7 +43,14 @@ namespace test { // thread. class PeerScenario { public: - PeerScenario(); + // The name is used for log output when those are enabled by the --peer_logs + // command line flag. Optionally, the TestInfo struct available in gtest can + // be used to automatically generate a path based on the test name. + explicit PeerScenario(const testing::TestInfo& test_info); + explicit PeerScenario(std::string file_name); + explicit PeerScenario( + std::unique_ptr log_writer_manager); + NetworkEmulationManagerImpl* net() { return &net_; } rtc::Thread* thread() { return signaling_thread_; } @@ -49,6 +58,8 @@ class PeerScenario { // The client will share the signaling thread with the scenario. To maintain // control of destruction order, ownership is kept within the scenario. PeerScenarioClient* CreateClient(PeerScenarioClient::Config config); + PeerScenarioClient* CreateClient(std::string name, + PeerScenarioClient::Config config); // Sets up a signaling route that can be used for SDP and ICE. SignalingRoute ConnectSignaling(PeerScenarioClient* caller, @@ -93,7 +104,11 @@ class PeerScenario { }; Clock* clock() { return Clock::GetRealTimeClock(); } + std::unique_ptr GetLogWriterFactory( + std::string name); + rtc::Thread* const signaling_thread_; + const std::unique_ptr log_writer_manager_; std::list video_quality_pairs_; NetworkEmulationManagerImpl net_; std::list peer_clients_; diff --git a/test/peer_scenario/peer_scenario_client.cc b/test/peer_scenario/peer_scenario_client.cc index f94d871885..28cbb6e22c 100644 --- a/test/peer_scenario/peer_scenario_client.cc +++ b/test/peer_scenario/peer_scenario_client.cc @@ -113,11 +113,14 @@ class LambdaPeerConnectionObserver final : public PeerConnectionObserver { }; } // namespace -PeerScenarioClient::PeerScenarioClient(NetworkEmulationManager* net, - rtc::Thread* signaling_thread, - PeerScenarioClient::Config config) +PeerScenarioClient::PeerScenarioClient( + NetworkEmulationManager* net, + rtc::Thread* signaling_thread, + std::unique_ptr log_writer_factory, + PeerScenarioClient::Config config) : endpoints_(CreateEndpoints(net, config.endpoints)), signaling_thread_(signaling_thread), + log_writer_factory_(std::move(log_writer_factory)), worker_thread_(rtc::Thread::Create()), handlers_(config.handlers), observer_(new LambdaPeerConnectionObserver(&handlers_)) { @@ -193,6 +196,10 @@ PeerScenarioClient::PeerScenarioClient(NetworkEmulationManager* net, cricket::PORTALLOCATOR_DISABLE_TCP); peer_connection_ = pc_factory_->CreatePeerConnection(config.rtc_config, std::move(pc_deps)); + if (log_writer_factory_) { + peer_connection_->StartRtcEventLog(log_writer_factory_->Create(".rtc.dat"), + /*output_period_ms=*/1000); + } } EmulatedEndpoint* PeerScenarioClient::endpoint(int index) { diff --git a/test/peer_scenario/peer_scenario_client.h b/test/peer_scenario/peer_scenario_client.h index 56ecbab606..404ae90048 100644 --- a/test/peer_scenario/peer_scenario_client.h +++ b/test/peer_scenario/peer_scenario_client.h @@ -21,6 +21,7 @@ #include "api/peer_connection_interface.h" #include "api/test/network_emulation_manager.h" #include "pc/test/frame_generator_capturer_video_track_source.h" +#include "test/logging/log_writer.h" namespace webrtc { namespace test { @@ -75,7 +76,6 @@ class PeerScenarioClient { }; absl::optional pulsed_noise = PulsedNoise(); } audio; - std::string client_name; // The created endpoints can be accessed using the map key as |index| in // PeerScenarioClient::endpoint(index). std::map endpoints = { @@ -102,9 +102,11 @@ class PeerScenarioClient { RtpSenderInterface* sender; }; - PeerScenarioClient(NetworkEmulationManager* net, - rtc::Thread* signaling_thread, - Config config); + PeerScenarioClient( + NetworkEmulationManager* net, + rtc::Thread* signaling_thread, + std::unique_ptr log_writer_factory, + Config config); PeerConnectionFactoryInterface* factory() { return pc_factory_.get(); } PeerConnectionInterface* pc() { @@ -143,6 +145,7 @@ class PeerScenarioClient { private: const std::map endpoints_; rtc::Thread* const signaling_thread_; + const std::unique_ptr log_writer_factory_; const std::unique_ptr worker_thread_; CallbackHandlers handlers_ RTC_GUARDED_BY(signaling_thread_); const std::unique_ptr observer_; diff --git a/test/peer_scenario/tests/peer_scenario_quality_test.cc b/test/peer_scenario/tests/peer_scenario_quality_test.cc index 17e5952d06..11aab07c0b 100644 --- a/test/peer_scenario/tests/peer_scenario_quality_test.cc +++ b/test/peer_scenario/tests/peer_scenario_quality_test.cc @@ -18,7 +18,7 @@ TEST(PeerScenarioQualityTest, PsnrIsCollected) { VideoQualityAnalyzerConfig analyzer_config; analyzer_config.thread = rtc::Thread::Current(); VideoQualityAnalyzer analyzer(analyzer_config); - PeerScenario s; + PeerScenario s(*test_info_); auto caller = s.CreateClient(PeerScenarioClient::Config()); auto callee = s.CreateClient(PeerScenarioClient::Config()); PeerScenarioClient::VideoSendTrackConfig video_conf; diff --git a/test/peer_scenario/tests/remote_estimate_test.cc b/test/peer_scenario/tests/remote_estimate_test.cc index 6cadedc335..998853293c 100644 --- a/test/peer_scenario/tests/remote_estimate_test.cc +++ b/test/peer_scenario/tests/remote_estimate_test.cc @@ -41,7 +41,7 @@ absl::optional GetRtpPacketExtensions( } // namespace TEST(RemoteEstimateEndToEnd, OfferedCapabilityIsInAnswer) { - PeerScenario s; + PeerScenario s(*test_info_); auto* caller = s.CreateClient(PeerScenarioClient::Config()); auto* callee = s.CreateClient(PeerScenarioClient::Config()); @@ -74,7 +74,7 @@ TEST(RemoteEstimateEndToEnd, AudioUsesAbsSendTimeExtension) { ScopedFieldTrials trials("WebRTC-KeepAbsSendTimeExtension/Enabled/"); // Defined before PeerScenario so it gets destructed after, to avoid use after free. rtc::Event received_abs_send_time; - PeerScenario s; + PeerScenario s(*test_info_); auto* caller = s.CreateClient(PeerScenarioClient::Config()); auto* callee = s.CreateClient(PeerScenarioClient::Config());