From 0cfaa610ca17016be030709bdba17340dffa8c6a Mon Sep 17 00:00:00 2001 From: Victor Boivie Date: Fri, 18 Mar 2022 09:16:35 +0100 Subject: [PATCH] dcsctp: Add test case for pending paused streams This use case was missing test coverage and sufficient comments in the code. Bug: None Change-Id: I95b54a64f714b68a347fdbeef79eb38e715adbc3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257166 Reviewed-by: Harald Alvestrand Commit-Queue: Victor Boivie Cr-Commit-Position: refs/heads/main@{#36393} --- net/dcsctp/tx/rr_send_queue.cc | 4 +++- net/dcsctp/tx/rr_send_queue_test.cc | 30 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/net/dcsctp/tx/rr_send_queue.cc b/net/dcsctp/tx/rr_send_queue.cc index f8f5ff2946..68db6f1870 100644 --- a/net/dcsctp/tx/rr_send_queue.cc +++ b/net/dcsctp/tx/rr_send_queue.cc @@ -44,7 +44,9 @@ bool RRSendQueue::OutgoingStream::HasDataToSend(TimeMs now) { while (!items_.empty()) { RRSendQueue::OutgoingStream::Item& item = items_.front(); if (item.message_id.has_value()) { - // Already partially sent messages can always continue to be sent. + // Already partially sent messages can always continue to be sent. This + // ensures e.g. that paused streams with partially sent messages get to + // send the partial message in full before resetting. return true; } diff --git a/net/dcsctp/tx/rr_send_queue_test.cc b/net/dcsctp/tx/rr_send_queue_test.cc index 425027762d..78f7616766 100644 --- a/net/dcsctp/tx/rr_send_queue_test.cc +++ b/net/dcsctp/tx/rr_send_queue_test.cc @@ -323,6 +323,36 @@ TEST_F(RRSendQueueTest, EnqueuedItemsArePausedDuringStreamReset) { EXPECT_EQ(buf_.total_buffered_amount(), 0u); } +TEST_F(RRSendQueueTest, PausedStreamsStillSendPartialMessagesUntilEnd) { + constexpr size_t kPayloadSize = 100; + constexpr size_t kFragmentSize = 50; + std::vector payload(kPayloadSize); + + buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload)); + buf_.Add(kNow, DcSctpMessage(kStreamID, kPPID, payload)); + + absl::optional chunk_one = + buf_.Produce(kNow, kFragmentSize); + ASSERT_TRUE(chunk_one.has_value()); + EXPECT_EQ(chunk_one->data.stream_id, kStreamID); + EXPECT_EQ(buf_.total_buffered_amount(), 2 * kPayloadSize - kFragmentSize); + + // This will stop the second message from being sent. + StreamID stream_ids[] = {StreamID(1)}; + buf_.PrepareResetStreams(stream_ids); + EXPECT_EQ(buf_.total_buffered_amount(), 1 * kPayloadSize - kFragmentSize); + + // Should still produce fragments until end of message. + absl::optional chunk_two = + buf_.Produce(kNow, kFragmentSize); + ASSERT_TRUE(chunk_two.has_value()); + EXPECT_EQ(chunk_two->data.stream_id, kStreamID); + EXPECT_EQ(buf_.total_buffered_amount(), 0ul); + + // But shouldn't produce any more messages as the stream is paused. + EXPECT_FALSE(buf_.Produce(kNow, kFragmentSize).has_value()); +} + TEST_F(RRSendQueueTest, CommittingResetsSSN) { std::vector payload(50);