diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn index fb0bc55ee1..4113978894 100644 --- a/test/network/BUILD.gn +++ b/test/network/BUILD.gn @@ -157,6 +157,7 @@ if (rtc_include_tests) { ] deps = [ ":emulated_network", + "../../api/transport:network_control", "../../api/transport:test_feedback_generator_interface", "../../call:simulated_network", "../../rtc_base:checks", diff --git a/test/network/feedback_generator.cc b/test/network/feedback_generator.cc index f0903dd3e7..68fbcc02a5 100644 --- a/test/network/feedback_generator.cc +++ b/test/network/feedback_generator.cc @@ -10,6 +10,7 @@ #include "test/network/feedback_generator.h" #include "absl/memory/memory.h" +#include "api/transport/network_types.h" #include "rtc_base/checks.h" namespace webrtc { @@ -39,6 +40,7 @@ void FeedbackGeneratorImpl::SendPacket(size_t size) { sent.send_time = Now(); sent.size = DataSize::Bytes(size); sent.sequence_number = sequence_number_++; + sent_packets_.push(sent); route_.SendRequest(size, sent); } @@ -69,18 +71,41 @@ void FeedbackGeneratorImpl::OnRequest(SentPacket packet, PacketResult result; result.sent_packet = packet; result.receive_time = arrival_time; - builder_.packet_feedbacks.push_back(result); - Timestamp first_recv = builder_.packet_feedbacks.front().receive_time; + received_packets_.push_back(result); + Timestamp first_recv = received_packets_.front().receive_time; if (Now() - first_recv > conf_.feedback_interval) { - route_.SendResponse(conf_.feedback_packet_size.bytes(), builder_); - builder_ = {}; + route_.SendResponse(conf_.feedback_packet_size.bytes(), + std::move(received_packets_)); + received_packets_ = {}; } } -void FeedbackGeneratorImpl::OnResponse(TransportPacketsFeedback packet, +void FeedbackGeneratorImpl::OnResponse(std::vector packet_results, Timestamp arrival_time) { - packet.feedback_time = arrival_time; - feedback_.push_back(packet); + TransportPacketsFeedback feedback; + feedback.feedback_time = arrival_time; + std::vector::const_iterator received_packet_iterator = + packet_results.begin(); + while (received_packet_iterator != packet_results.end()) { + RTC_DCHECK(!sent_packets_.empty() && + sent_packets_.front().sequence_number <= + received_packet_iterator->sent_packet.sequence_number) + << "reordering not implemented"; + if (sent_packets_.front().sequence_number < + received_packet_iterator->sent_packet.sequence_number) { + // Packet lost. + PacketResult lost; + lost.sent_packet = sent_packets_.front(); + feedback.packet_feedbacks.push_back(lost); + } + if (sent_packets_.front().sequence_number == + received_packet_iterator->sent_packet.sequence_number) { + feedback.packet_feedbacks.push_back(*received_packet_iterator); + ++received_packet_iterator; + } + sent_packets_.pop(); + } + feedback_.push_back(feedback); } } // namespace webrtc diff --git a/test/network/feedback_generator.h b/test/network/feedback_generator.h index 98ac01c7a6..ecd4597d3f 100644 --- a/test/network/feedback_generator.h +++ b/test/network/feedback_generator.h @@ -10,10 +10,12 @@ #ifndef TEST_NETWORK_FEEDBACK_GENERATOR_H_ #define TEST_NETWORK_FEEDBACK_GENERATOR_H_ -#include +#include +#include #include #include +#include "api/transport/network_types.h" #include "api/transport/test/feedback_generator_interface.h" #include "call/simulated_network.h" #include "test/network/network_emulation.h" @@ -24,7 +26,7 @@ namespace webrtc { class FeedbackGeneratorImpl : public FeedbackGenerator, - public TwoWayFakeTrafficRoute:: + public TwoWayFakeTrafficRoute>:: TrafficHandlerInterface { public: explicit FeedbackGeneratorImpl(Config config); @@ -39,7 +41,7 @@ class FeedbackGeneratorImpl void SetSendLinkCapacity(DataRate capacity) override; void OnRequest(SentPacket packet, Timestamp arrival_time) override; - void OnResponse(TransportPacketsFeedback packet, + void OnResponse(std::vector packet_results, Timestamp arrival_time) override; private: @@ -47,9 +49,10 @@ class FeedbackGeneratorImpl ::webrtc::test::NetworkEmulationManagerImpl net_; SimulatedNetwork* const send_link_; SimulatedNetwork* const ret_link_; - TwoWayFakeTrafficRoute route_; + TwoWayFakeTrafficRoute> route_; - TransportPacketsFeedback builder_; + std::queue sent_packets_; + std::vector received_packets_; std::vector feedback_; int64_t sequence_number_ = 1; }; diff --git a/test/network/feedback_generator_unittest.cc b/test/network/feedback_generator_unittest.cc index ca04bd3c9f..9a577bea00 100644 --- a/test/network/feedback_generator_unittest.cc +++ b/test/network/feedback_generator_unittest.cc @@ -28,4 +28,20 @@ TEST(FeedbackGeneratorTest, ReportsFeedbackForSentPackets) { } } } + +TEST(FeedbackGeneratorTest, FeedbackIncludesLostPackets) { + size_t kPacketSize = 1000; + auto gen = CreateFeedbackGenerator(FeedbackGenerator::Config()); + BuiltInNetworkBehaviorConfig send_config_with_loss; + send_config_with_loss.loss_percent = 50; + gen->SetSendConfig(send_config_with_loss); + for (int i = 0; i < 20; ++i) { + gen->SendPacket(kPacketSize); + gen->Sleep(TimeDelta::Millis(5)); + } + auto feedback_list = gen->PopFeedback(); + ASSERT_GT(feedback_list.size(), 0u); + EXPECT_NEAR(feedback_list[0].LostWithSendInfo().size(), + feedback_list[0].ReceivedWithSendInfo().size(), 2); +} } // namespace webrtc