Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Unified Diff: webrtc/modules/congestion_controller/congestion_controller_unittest.cc

Issue 2725823002: Move delay_based_bwe_ into CongestionController (Closed)
Patch Set: More refactoring + UTs moved. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/congestion_controller/congestion_controller_unittest.cc
diff --git a/webrtc/modules/congestion_controller/congestion_controller_unittest.cc b/webrtc/modules/congestion_controller/congestion_controller_unittest.cc
index ca0d28fcd5c8cfbd819cdbcd9c98ac3bc62f7738..6df6381790acdd97eb96f8e89677d27acbf5ccab 100644
--- a/webrtc/modules/congestion_controller/congestion_controller_unittest.cc
+++ b/webrtc/modules/congestion_controller/congestion_controller_unittest.cc
@@ -9,12 +9,13 @@
*/
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
-#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
+#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
#include "webrtc/modules/congestion_controller/include/mock/mock_congestion_controller.h"
#include "webrtc/modules/pacing/mock/mock_paced_sender.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
@@ -27,6 +28,8 @@ using testing::SaveArg;
using testing::StrictMock;
namespace {
+const webrtc::PacedPacketInfo kPacingInfo0(0, 5, 2000);
+const webrtc::PacedPacketInfo kPacingInfo1(1, 8, 4000);
// Helper to convert some time format to resolution used in absolute send time
// header extension, rounded upwards. |t| is the time to convert, in some
@@ -36,6 +39,34 @@ uint32_t AbsSendTime(int64_t t, int64_t denom) {
return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful;
}
+// TODO(elad.alon): This is not meant to be landed like this. Ask reviewers
elad.alon_webrtc.org 2017/03/02 11:51:47 Soliciting feedback. :-)
+// where would be a good place to put ComparePacketVectors(), so that it would
+// be visible to both unit-test suites.
+void ComparePacketVectors(const std::vector<webrtc::PacketFeedback>& truth,
+ const std::vector<webrtc::PacketFeedback>& input) {
+ ASSERT_EQ(truth.size(), input.size());
+ size_t len = truth.size();
+ // truth contains the input data for the test, and input is what will be
+ // sent to the bandwidth estimator. truth.arrival_tims_ms is used to
+ // populate the transport feedback messages. As these times may be changed
+ // (because of resolution limits in the packets, and because of the time
+ // base adjustment performed by the TransportFeedbackAdapter at the first
+ // packet, the truth[x].arrival_time and input[x].arrival_time may not be
+ // equal. However, the difference must be the same for all x.
+ int64_t arrival_time_delta =
+ truth[0].arrival_time_ms - input[0].arrival_time_ms;
+ for (size_t i = 0; i < len; ++i) {
+ RTC_CHECK(truth[i].arrival_time_ms != webrtc::PacketFeedback::kNotReceived);
+ if (input[i].arrival_time_ms != webrtc::PacketFeedback::kNotReceived) {
+ EXPECT_EQ(truth[i].arrival_time_ms,
+ input[i].arrival_time_ms + arrival_time_delta);
+ }
+ EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
+ EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
+ EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
+ EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info);
+ }
+}
} // namespace
namespace webrtc {
@@ -51,7 +82,9 @@ class CongestionControllerTest : public ::testing::Test {
std::unique_ptr<PacedSender> pacer(pacer_); // Passes ownership.
controller_.reset(new CongestionController(
&clock_, &observer_, &remote_bitrate_observer_, &event_log_,
- &packet_router_, std::move(pacer)));
+ &packet_router_, std::move(pacer),
+ std::unique_ptr<BitrateController>(
+ BitrateController::CreateBitrateController(&clock_, &event_log_))));
bandwidth_observer_.reset(
controller_->GetBitrateController()->CreateRtcpBandwidthObserver());
@@ -62,6 +95,29 @@ class CongestionControllerTest : public ::testing::Test {
controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
}
+ void OnSentPacket(const PacketFeedback& packet_feedback) {
+ controller_->AddPacket(packet_feedback.sequence_number,
+ packet_feedback.payload_size,
+ packet_feedback.pacing_info);
+ controller_->OnSentPacket(rtc::SentPacket(packet_feedback.sequence_number,
+ packet_feedback.send_time_ms));
+ }
+
+ class MockBitrateControllerAdapter : public MockBitrateController {
stefan-webrtc 2017/03/02 15:58:07 I would prefer not to have this mock, and to not e
+ public:
+ explicit MockBitrateControllerAdapter(CongestionControllerTest* owner)
+ : MockBitrateController(), owner_(owner) {}
+
+ ~MockBitrateControllerAdapter() override {}
+
+ void OnDelayBasedBweResult(const DelayBasedBwe::Result& result) override {
+ owner_->target_bitrate_bps_ =
+ rtc::Optional<uint32_t>(result.target_bitrate_bps);
+ }
+
+ CongestionControllerTest* const owner_;
+ };
+
SimulatedClock clock_;
StrictMock<MockCongestionObserver> observer_;
NiceMock<MockPacedSender>* pacer_;
@@ -71,6 +127,7 @@ class CongestionControllerTest : public ::testing::Test {
PacketRouter packet_router_;
std::unique_ptr<CongestionController> controller_;
const uint32_t kInitialBitrateBps = 60000;
+ rtc::Optional<uint32_t> target_bitrate_bps_;
};
TEST_F(CongestionControllerTest, OnNetworkChanged) {
@@ -217,9 +274,11 @@ TEST_F(CongestionControllerTest, OnReceivedPacketWithAbsSendTime) {
NiceMock<MockCongestionObserver> observer;
StrictMock<MockRemoteBitrateObserver> remote_bitrate_observer;
std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>());
- controller_.reset(
- new CongestionController(&clock_, &observer, &remote_bitrate_observer,
- &event_log_, &packet_router_, std::move(pacer)));
+ controller_.reset(new CongestionController(
+ &clock_, &observer, &remote_bitrate_observer, &event_log_,
+ &packet_router_, std::move(pacer),
+ std::unique_ptr<BitrateController>(
+ BitrateController::CreateBitrateController(&clock_, &event_log_))));
size_t payload_size = 1000;
RTPHeader header;
@@ -240,5 +299,141 @@ TEST_F(CongestionControllerTest, OnReceivedPacketWithAbsSendTime) {
ASSERT_EQ(1u, ssrcs.size());
EXPECT_EQ(header.ssrc, ssrcs[0]);
}
+
+TEST_F(CongestionControllerTest, UpdatesDelayBasedEstimate) {
+ NiceMock<MockCongestionObserver> observer;
+ StrictMock<MockRemoteBitrateObserver> remote_bitrate_observer;
+ std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>());
+ controller_.reset(
+ new CongestionController(&clock_, &observer, &remote_bitrate_observer,
+ &event_log_, &packet_router_, std::move(pacer),
+ std::unique_ptr<BitrateController>(
+ new MockBitrateControllerAdapter(this))));
+
+ uint16_t seq_num = 0;
+ size_t kPayloadSize = 1000;
+ // The test must run and insert packets/feedback long enough that the
+ // BWE computes a valid estimate.
+ const int64_t kRunTimeMs = 6000;
+ int64_t start_time_ms = clock_.TimeInMilliseconds();
+ while (clock_.TimeInMilliseconds() - start_time_ms < kRunTimeMs) {
+ PacketFeedback packet(clock_.TimeInMilliseconds(),
+ clock_.TimeInMilliseconds(), seq_num, kPayloadSize,
+ PacedPacketInfo());
+ OnSentPacket(packet);
+ // Create expected feedback and send into adapter.
+ std::unique_ptr<rtcp::TransportFeedback> feedback(
+ new rtcp::TransportFeedback());
+ feedback->SetBase(packet.sequence_number, packet.arrival_time_ms * 1000);
+ EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ rtc::Buffer raw_packet = feedback->Build();
+ feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(),
+ raw_packet.size());
+ EXPECT_TRUE(feedback.get() != nullptr);
+ controller_->OnTransportFeedback(*feedback.get());
+ clock_.AdvanceTimeMilliseconds(50);
+ ++seq_num;
+ }
stefan-webrtc 2017/03/02 15:58:07 Keep this loop, and also add a similar after: whi
+
+ EXPECT_TRUE(target_bitrate_bps_);
+}
+
+TEST_F(CongestionControllerTest, LongFeedbackDelays) {
+ // Custom setup
+ std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>());
+ auto mock_bitrate_controller = std::unique_ptr<MockBitrateControllerAdapter>(
+ new MockBitrateControllerAdapter(this));
+ EXPECT_CALL(*mock_bitrate_controller, SetBitrates(_, _, _));
+ EXPECT_CALL(*mock_bitrate_controller, GetNetworkParameters(_, _, _));
+ EXPECT_CALL(observer_, OnNetworkChanged(_, _, _, _));
+ controller_.reset(new CongestionController(
+ &clock_, &observer_, &remote_bitrate_observer_, &event_log_,
+ &packet_router_, std::move(pacer),
+ std::unique_ptr<BitrateController>(std::move(mock_bitrate_controller))));
+ controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
+
+ const int64_t kFeedbackTimeoutMs = 60001;
+ const int kMaxConsecutiveFailedLookups = 5;
+ for (int i = 0; i < kMaxConsecutiveFailedLookups; ++i) {
+ std::vector<PacketFeedback> packets;
+ packets.push_back(
+ PacketFeedback(i * 100, 2 * i * 100, 0, 1500, kPacingInfo0));
+ packets.push_back(
+ PacketFeedback(i * 100 + 10, 2 * i * 100 + 10, 1, 1500, kPacingInfo0));
+ packets.push_back(
+ PacketFeedback(i * 100 + 20, 2 * i * 100 + 20, 2, 1500, kPacingInfo0));
+ packets.push_back(
+ PacketFeedback(i * 100 + 30, 2 * i * 100 + 30, 3, 1500, kPacingInfo1));
+ packets.push_back(
+ PacketFeedback(i * 100 + 40, 2 * i * 100 + 40, 4, 1500, kPacingInfo1));
+
+ for (const PacketFeedback& packet : packets)
+ OnSentPacket(packet);
+
+ rtcp::TransportFeedback feedback;
+ feedback.SetBase(packets[0].sequence_number,
+ packets[0].arrival_time_ms * 1000);
+
+ for (const PacketFeedback& packet : packets) {
+ EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ }
+
+ feedback.Build();
+
+ clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs);
+ PacketFeedback later_packet(kFeedbackTimeoutMs + i * 100 + 40,
+ kFeedbackTimeoutMs + i * 200 + 40, 5, 1500,
+ kPacingInfo1);
+ OnSentPacket(later_packet);
+
+ controller_->OnTransportFeedback(feedback);
+
+ // Check that packets have timed out.
+ for (PacketFeedback& packet : packets) {
+ packet.send_time_ms = -1;
+ packet.payload_size = 0;
+ packet.pacing_info = PacedPacketInfo();
+ }
+ ComparePacketVectors(packets, controller_->GetTransportFeedbackVector());
+ }
+
+ // Target bitrate should have halved due to feedback delays.
+ EXPECT_EQ(kInitialBitrateBps / 2, target_bitrate_bps_);
+
+ // Test with feedback that isn't late enough to time out.
+ {
+ std::vector<PacketFeedback> packets;
+ packets.push_back(PacketFeedback(100, 200, 0, 1500, kPacingInfo0));
+ packets.push_back(PacketFeedback(110, 210, 1, 1500, kPacingInfo0));
+ packets.push_back(PacketFeedback(120, 220, 2, 1500, kPacingInfo0));
+ packets.push_back(PacketFeedback(130, 230, 3, 1500, kPacingInfo1));
+ packets.push_back(PacketFeedback(140, 240, 4, 1500, kPacingInfo1));
+
+ for (const PacketFeedback& packet : packets)
+ OnSentPacket(packet);
+
+ rtcp::TransportFeedback feedback;
+ feedback.SetBase(packets[0].sequence_number,
+ packets[0].arrival_time_ms * 1000);
+
+ for (const PacketFeedback& packet : packets) {
+ EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ }
+
+ feedback.Build();
+
+ clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs - 1);
+ PacketFeedback later_packet(kFeedbackTimeoutMs + 140,
+ kFeedbackTimeoutMs + 240, 5, 1500,
+ kPacingInfo1);
+ OnSentPacket(later_packet);
+
+ controller_->OnTransportFeedback(feedback);
+ ComparePacketVectors(packets, controller_->GetTransportFeedbackVector());
+ }
+}
} // namespace test
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698