diff options
Diffstat (limited to 'third_party/libwebrtc/test/peer_scenario')
7 files changed, 208 insertions, 14 deletions
diff --git a/third_party/libwebrtc/test/peer_scenario/BUILD.gn b/third_party/libwebrtc/test/peer_scenario/BUILD.gn index 18f81a56e6..e1d164a47d 100644 --- a/third_party/libwebrtc/test/peer_scenario/BUILD.gn +++ b/third_party/libwebrtc/test/peer_scenario/BUILD.gn @@ -53,7 +53,9 @@ if (rtc_include_tests) { "../../media:rtp_utils", "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", + "../../p2p:basic_port_allocator", "../../p2p:rtc_p2p", + "../../p2p:transport_description", "../../pc:channel", "../../pc:jsep_transport_controller", "../../pc:pc_test_utils", diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc index 1397b32fe3..3ba4fdb677 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc @@ -370,10 +370,13 @@ void PeerScenarioClient::CreateAndSetSdp( void PeerScenarioClient::SetSdpOfferAndGetAnswer( std::string remote_offer, + std::function<void()> remote_description_set, std::function<void(std::string)> answer_handler) { if (!signaling_thread_->IsCurrent()) { - signaling_thread_->PostTask( - [=] { SetSdpOfferAndGetAnswer(remote_offer, answer_handler); }); + signaling_thread_->PostTask([=] { + SetSdpOfferAndGetAnswer(remote_offer, remote_description_set, + answer_handler); + }); return; } RTC_DCHECK_RUN_ON(signaling_thread_); @@ -381,6 +384,11 @@ void PeerScenarioClient::SetSdpOfferAndGetAnswer( CreateSessionDescription(SdpType::kOffer, remote_offer), rtc::make_ref_counted<LambdaSetRemoteDescriptionObserver>([=](RTCError) { RTC_DCHECK_RUN_ON(signaling_thread_); + if (remote_description_set) { + // Allow the caller to modify transceivers + // before creating the answer. + remote_description_set(); + } peer_connection_->CreateAnswer( rtc::make_ref_counted<LambdaCreateSessionDescriptionObserver>( [=](std::unique_ptr<SessionDescriptionInterface> answer) { diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h index e863757759..cb025e9879 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h @@ -147,6 +147,7 @@ class PeerScenarioClient { std::function<void(SessionDescriptionInterface*)> munge_offer, std::function<void(std::string)> offer_handler); void SetSdpOfferAndGetAnswer(std::string remote_offer, + std::function<void()> remote_description_set, std::function<void(std::string)> answer_handler); void SetSdpAnswer( std::string remote_answer, diff --git a/third_party/libwebrtc/test/peer_scenario/signaling_route.cc b/third_party/libwebrtc/test/peer_scenario/signaling_route.cc index eeec7c8657..8688c1abd8 100644 --- a/third_party/libwebrtc/test/peer_scenario/signaling_route.cc +++ b/third_party/libwebrtc/test/peer_scenario/signaling_route.cc @@ -59,6 +59,7 @@ void StartSdpNegotiation( CrossTrafficRoute* ret_route, std::function<void(SessionDescriptionInterface* offer)> munge_offer, std::function<void(SessionDescriptionInterface*)> modify_offer, + std::function<void()> callee_remote_description_set, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { caller->CreateAndSetSdp(munge_offer, [=](std::string sdp_offer) { if (modify_offer) { @@ -67,11 +68,14 @@ void StartSdpNegotiation( RTC_CHECK(offer->ToString(&sdp_offer)); } send_route->NetworkDelayedAction(kSdpPacketSize, [=] { - callee->SetSdpOfferAndGetAnswer(sdp_offer, [=](std::string answer) { - ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { - caller->SetSdpAnswer(std::move(answer), std::move(exchange_finished)); - }); - }); + callee->SetSdpOfferAndGetAnswer( + sdp_offer, std::move(callee_remote_description_set), + [=](std::string answer) { + ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { + caller->SetSdpAnswer(std::move(answer), + std::move(exchange_finished)); + }); + }); }); }); } @@ -92,22 +96,39 @@ void SignalingRoute::StartIceSignaling() { } void SignalingRoute::NegotiateSdp( + std::function<void(SessionDescriptionInterface* offer)> munge_offer, + std::function<void(SessionDescriptionInterface* offer)> modify_offer, + std::function<void()> callee_remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished) { + StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, + modify_offer, callee_remote_description_set, + exchange_finished); +} + +void SignalingRoute::NegotiateSdp( std::function<void(SessionDescriptionInterface*)> munge_offer, std::function<void(SessionDescriptionInterface*)> modify_offer, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, - modify_offer, exchange_finished); + NegotiateSdp(munge_offer, modify_offer, {}, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function<void(SessionDescriptionInterface*)> modify_offer, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - NegotiateSdp({}, modify_offer, exchange_finished); + NegotiateSdp({}, modify_offer, {}, exchange_finished); +} + +void SignalingRoute::NegotiateSdp( + std::function<void()> remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished) { + NegotiateSdp({}, {}, remote_description_set, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - NegotiateSdp({}, {}, exchange_finished); + NegotiateSdp({}, {}, {}, exchange_finished); } } // namespace test diff --git a/third_party/libwebrtc/test/peer_scenario/signaling_route.h b/third_party/libwebrtc/test/peer_scenario/signaling_route.h index a95ae5c9f7..9b317d2552 100644 --- a/third_party/libwebrtc/test/peer_scenario/signaling_route.h +++ b/third_party/libwebrtc/test/peer_scenario/signaling_route.h @@ -35,12 +35,21 @@ class SignalingRoute { // The `munge_offer` callback is used to modify an offer between its creation // and set local description. This behavior is forbidden according to the spec // but available here in order to allow test coverage on corner cases. - // The `exchange_finished` callback is called with the answer produced after - // SDP negotations has completed. + // `callee_remote_description_set` is invoked when callee has applied the + // offer but not yet created an answer. The purpose is to allow tests to + // modify transceivers created from the offer. The `exchange_finished` + // callback is called with the answer produced after SDP negotations has + // completed. // TODO(srte): Handle lossy links. void NegotiateSdp( std::function<void(SessionDescriptionInterface* offer)> munge_offer, std::function<void(SessionDescriptionInterface* offer)> modify_offer, + std::function<void()> callee_remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished); + void NegotiateSdp( + std::function<void(SessionDescriptionInterface* offer)> munge_offer, + std::function<void(SessionDescriptionInterface* offer)> modify_offer, std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); void NegotiateSdp( @@ -48,6 +57,10 @@ class SignalingRoute { std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); void NegotiateSdp( + std::function<void()> remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished); + void NegotiateSdp( std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); SignalingRoute reverse() { diff --git a/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc index a7a17bbfd1..f8eaa47858 100644 --- a/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc +++ b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc @@ -25,6 +25,9 @@ namespace webrtc { namespace test { using ::testing::SizeIs; +using ::testing::Test; +using ::testing::ValuesIn; +using ::testing::WithParamInterface; rtc::scoped_refptr<const RTCStatsReport> GetStatsAndProcess( PeerScenario& s, @@ -124,5 +127,152 @@ TEST(BweRampupTest, RampUpWithUndemuxableRtpPackets) { // ensure BWE has increased beyond noise levels. EXPECT_GT(final_bwe, initial_bwe + DataRate::KilobitsPerSec(345)); } + +struct InitialProbeTestParams { + DataRate network_capacity; + DataRate expected_bwe_min; +}; +class BweRampupWithInitialProbeTest + : public Test, + public WithParamInterface<InitialProbeTestParams> {}; + +INSTANTIATE_TEST_SUITE_P( + BweRampupWithInitialProbeTest, + BweRampupWithInitialProbeTest, + ValuesIn<InitialProbeTestParams>( + {{ + .network_capacity = DataRate::KilobitsPerSec(3000), + .expected_bwe_min = DataRate::KilobitsPerSec(2500), + }, + { + .network_capacity = webrtc::DataRate::KilobitsPerSec(500), + .expected_bwe_min = webrtc::DataRate::KilobitsPerSec(400), + }})); + +// Test that caller and callee BWE rampup even if no media packets are sent. +// - BandWidthEstimationSettings.allow_probe_without_media must be set. +// - A Video RtpTransceiver with RTX support needs to be negotiated. +TEST_P(BweRampupWithInitialProbeTest, BweRampUpBothDirectionsWithoutMedia) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + InitialProbeTestParams test_params = GetParam(); + + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto video_result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); + ASSERT_EQ(video_result.error().type(), RTCErrorType::NONE); + + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + callee->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + + auto node_builder = + s.net()->NodeBuilder().capacity_kbps(test_params.network_capacity.kbps()); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + signaling.StartIceSignaling(); + + std::atomic<bool> offer_exchange_done(false); + signaling.NegotiateSdp( + [&]() { + // When remote description has been set, a transceiver is created. + // Set the diretion to sendrecv so that it can be used for BWE probing + // from callee -> caller. + ASSERT_THAT(callee->pc()->GetTransceivers(), SizeIs(1)); + ASSERT_TRUE( + callee->pc() + ->GetTransceivers()[0] + ->SetDirectionWithError(RtpTransceiverDirection::kSendRecv) + .ok()); + }, + [&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Test that 1s after offer/answer exchange finish, we have a BWE estimate, + // even though no video frames have been sent. + s.ProcessMessages(TimeDelta::Seconds(1)); + + auto callee_inbound_stats = + GetStatsAndProcess(s, callee)->GetStatsOfType<RTCInboundRtpStreamStats>(); + ASSERT_THAT(callee_inbound_stats, SizeIs(1)); + ASSERT_EQ(*callee_inbound_stats[0]->frames_received, 0u); + auto caller_inbound_stats = + GetStatsAndProcess(s, caller)->GetStatsOfType<RTCInboundRtpStreamStats>(); + ASSERT_THAT(caller_inbound_stats, SizeIs(1)); + ASSERT_EQ(*caller_inbound_stats[0]->frames_received, 0u); + + DataRate caller_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(caller_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(caller_bwe.kbps(), test_params.network_capacity.kbps()); + DataRate callee_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, callee)); + EXPECT_GT(callee_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(callee_bwe.kbps(), test_params.network_capacity.kbps()); +} + +// Test that we can reconfigure bandwidth estimation and send new BWE probes. +// In this test, camera is stopped, and some times later, the app want to get a +// new BWE estimate. +TEST(BweRampupTest, CanReconfigureBweAfterStopingVideo) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto node_builder = s.net()->NodeBuilder().capacity_kbps(1000); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + PeerScenarioClient::VideoSendTrack track = caller->CreateVideo("VIDEO", {}); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + + signaling.StartIceSignaling(); + + std::atomic<bool> offer_exchange_done(false); + signaling.NegotiateSdp([&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Send a TCP messages to the receiver using the same downlink node. + // This is done just to force a lower BWE than the link capacity. + webrtc::TcpMessageRoute* tcp_route = s.net()->CreateTcpRoute( + s.net()->CreateRoute({caller_node}), s.net()->CreateRoute({callee_node})); + DataRate bwe_before_restart = DataRate::Zero(); + + std::atomic<bool> message_delivered(false); + tcp_route->SendMessage( + /*size=*/5'00'000, + /*on_received=*/[&]() { message_delivered = true; }); + s.WaitAndProcess(&message_delivered); + bwe_before_restart = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + + // Camera is stopped. + track.capturer->Stop(); + s.ProcessMessages(TimeDelta::Seconds(2)); + + // Some time later, the app is interested in restarting BWE since we may want + // to resume video eventually. + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + s.ProcessMessages(TimeDelta::Seconds(1)); + DataRate bwe_after_restart = + GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(bwe_after_restart.kbps(), bwe_before_restart.kbps() + 300); + EXPECT_LT(bwe_after_restart.kbps(), 1000); +} + } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc index 4f478b4b2a..dced274e68 100644 --- a/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc +++ b/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc @@ -98,7 +98,6 @@ TEST_P(UnsignaledStreamTest, ReplacesUnsignaledStreamOnCompletedSignaling) { PeerScenarioClient::Config config = PeerScenarioClient::Config(); // Disable encryption so that we can inject a fake early media packet without // triggering srtp failures. - config.disable_encryption = true; auto* caller = s.CreateClient(config); auto* callee = s.CreateClient(config); |