Add test for many non-dropped packets in unreliable mode.
These tests document existing behavior; there are notes about where this behavior is either surprising or wrong. Bug: chromium:1148951 Change-Id: If9875fb744c44c129ff9949d1bab3d3d99f17b81 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217520 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34058}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
e7481a4199
commit
86bd92fca9
@ -1056,6 +1056,7 @@ if (rtc_include_tests && !build_with_chromium) {
|
|||||||
"../rtc_base/synchronization:mutex",
|
"../rtc_base/synchronization:mutex",
|
||||||
"../rtc_base/third_party/base64",
|
"../rtc_base/third_party/base64",
|
||||||
"../rtc_base/third_party/sigslot",
|
"../rtc_base/third_party/sigslot",
|
||||||
|
"../system_wrappers:field_trial",
|
||||||
"../system_wrappers:metrics",
|
"../system_wrappers:metrics",
|
||||||
"../test:field_trial",
|
"../test:field_trial",
|
||||||
"../test:fileutils",
|
"../test:fileutils",
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "rtc_base/gunit.h"
|
#include "rtc_base/gunit.h"
|
||||||
#include "rtc_base/ref_counted_object.h"
|
#include "rtc_base/ref_counted_object.h"
|
||||||
#include "rtc_base/virtual_socket_server.h"
|
#include "rtc_base/virtual_socket_server.h"
|
||||||
|
#include "system_wrappers/include/field_trial.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -622,7 +623,7 @@ TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDeliveredInReliableMode) {
|
|||||||
kDefaultTimeout);
|
kDefaultTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDeliveredInUnReliableMode) {
|
TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDroppedInUnreliableMode) {
|
||||||
CreatePeerConnectionWrappers();
|
CreatePeerConnectionWrappers();
|
||||||
ConnectFakeSignaling();
|
ConnectFakeSignaling();
|
||||||
DataChannelInit init;
|
DataChannelInit init;
|
||||||
@ -637,6 +638,9 @@ TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDeliveredInUnReliableMode) {
|
|||||||
kDefaultTimeout);
|
kDefaultTimeout);
|
||||||
// Cause a temporary network outage
|
// Cause a temporary network outage
|
||||||
virtual_socket_server()->set_drop_probability(1.0);
|
virtual_socket_server()->set_drop_probability(1.0);
|
||||||
|
// Send a few packets. Note that all get dropped only when all packets
|
||||||
|
// fit into the receiver receive window/congestion window, so that they
|
||||||
|
// actually get sent.
|
||||||
for (int i = 1; i <= 10; i++) {
|
for (int i = 1; i <= 10; i++) {
|
||||||
caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
|
caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
|
||||||
}
|
}
|
||||||
@ -659,6 +663,116 @@ TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDeliveredInUnReliableMode) {
|
|||||||
EXPECT_EQ(2u, callee()->data_observer()->received_message_count());
|
EXPECT_EQ(2u, callee()->data_observer()->received_message_count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(DataChannelIntegrationTest,
|
||||||
|
QueuedPacketsGetDroppedInLifetimeLimitedMode) {
|
||||||
|
CreatePeerConnectionWrappers();
|
||||||
|
ConnectFakeSignaling();
|
||||||
|
DataChannelInit init;
|
||||||
|
init.maxRetransmitTime = 1;
|
||||||
|
init.ordered = false;
|
||||||
|
caller()->CreateDataChannel(&init);
|
||||||
|
caller()->CreateAndSetAndSignalOffer();
|
||||||
|
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
|
||||||
|
ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
|
||||||
|
caller()->data_channel()->Send(DataBuffer("hello first"));
|
||||||
|
ASSERT_EQ_WAIT(1u, callee()->data_observer()->received_message_count(),
|
||||||
|
kDefaultTimeout);
|
||||||
|
// Cause a temporary network outage
|
||||||
|
virtual_socket_server()->set_drop_probability(1.0);
|
||||||
|
for (int i = 1; i <= 200; i++) {
|
||||||
|
caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
|
||||||
|
}
|
||||||
|
// Nothing should be delivered during outage.
|
||||||
|
// We do a short wait to verify that delivery count is still 1,
|
||||||
|
// and to make sure max packet lifetime (which is in ms) is exceeded.
|
||||||
|
WAIT(false, 10);
|
||||||
|
EXPECT_EQ(1u, callee()->data_observer()->received_message_count());
|
||||||
|
// Reverse the network outage.
|
||||||
|
virtual_socket_server()->set_drop_probability(0.0);
|
||||||
|
// Send a new packet, and wait for it to be delivered.
|
||||||
|
caller()->data_channel()->Send(DataBuffer("After block"));
|
||||||
|
EXPECT_EQ_WAIT("After block", callee()->data_observer()->last_message(),
|
||||||
|
kDefaultTimeout);
|
||||||
|
// Some messages should be lost, but first and last message should have
|
||||||
|
// been delivered.
|
||||||
|
// First, check that the protocol guarantee is preserved.
|
||||||
|
EXPECT_GT(202u, callee()->data_observer()->received_message_count());
|
||||||
|
EXPECT_LE(2u, callee()->data_observer()->received_message_count());
|
||||||
|
// Then, check that observed behavior (lose some messages) has not changed
|
||||||
|
if (webrtc::field_trial::IsEnabled("WebRTC-DataChannel-Dcsctp")) {
|
||||||
|
// DcSctp loses all messages. This is correct.
|
||||||
|
EXPECT_EQ(2u, callee()->data_observer()->received_message_count());
|
||||||
|
} else {
|
||||||
|
// Usrsctp loses some messages, but keeps messages not attempted.
|
||||||
|
// THIS IS THE WRONG BEHAVIOR. According to discussion in
|
||||||
|
// https://github.com/sctplab/usrsctp/issues/584, all these packets
|
||||||
|
// should be discarded.
|
||||||
|
// TODO(bugs.webrtc.org/12731): Fix this.
|
||||||
|
EXPECT_EQ(90u, callee()->data_observer()->received_message_count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(DataChannelIntegrationTest,
|
||||||
|
SomeQueuedPacketsGetDroppedInMaxRetransmitsMode) {
|
||||||
|
CreatePeerConnectionWrappers();
|
||||||
|
ConnectFakeSignaling();
|
||||||
|
DataChannelInit init;
|
||||||
|
init.maxRetransmits = 0;
|
||||||
|
init.ordered = false;
|
||||||
|
caller()->CreateDataChannel(&init);
|
||||||
|
caller()->CreateAndSetAndSignalOffer();
|
||||||
|
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
|
||||||
|
ASSERT_TRUE_WAIT(callee()->data_channel(), kDefaultTimeout);
|
||||||
|
caller()->data_channel()->Send(DataBuffer("hello first"));
|
||||||
|
ASSERT_EQ_WAIT(1u, callee()->data_observer()->received_message_count(),
|
||||||
|
kDefaultTimeout);
|
||||||
|
// Cause a temporary network outage
|
||||||
|
virtual_socket_server()->set_drop_probability(1.0);
|
||||||
|
// Fill the buffer until queued data starts to build
|
||||||
|
size_t packet_counter = 0;
|
||||||
|
while (caller()->data_channel()->buffered_amount() < 1 &&
|
||||||
|
packet_counter < 10000) {
|
||||||
|
packet_counter++;
|
||||||
|
caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
|
||||||
|
}
|
||||||
|
if (caller()->data_channel()->buffered_amount()) {
|
||||||
|
RTC_LOG(LS_INFO) << "Buffered data after " << packet_counter << " packets";
|
||||||
|
} else {
|
||||||
|
RTC_LOG(LS_INFO) << "No buffered data after " << packet_counter
|
||||||
|
<< " packets";
|
||||||
|
}
|
||||||
|
// Nothing should be delivered during outage.
|
||||||
|
// We do a short wait to verify that delivery count is still 1.
|
||||||
|
WAIT(false, 10);
|
||||||
|
EXPECT_EQ(1u, callee()->data_observer()->received_message_count());
|
||||||
|
// Reverse the network outage.
|
||||||
|
virtual_socket_server()->set_drop_probability(0.0);
|
||||||
|
// Send a new packet, and wait for it to be delivered.
|
||||||
|
caller()->data_channel()->Send(DataBuffer("After block"));
|
||||||
|
EXPECT_EQ_WAIT("After block", callee()->data_observer()->last_message(),
|
||||||
|
kDefaultTimeout);
|
||||||
|
// Some messages should be lost, but first and last message should have
|
||||||
|
// been delivered.
|
||||||
|
// Due to the fact that retransmissions are only counted when the packet
|
||||||
|
// goes on the wire, NOT when they are stalled in queue due to
|
||||||
|
// congestion, we expect some of the packets to be delivered, because
|
||||||
|
// congestion prevented them from being sent.
|
||||||
|
// Citation: https://tools.ietf.org/html/rfc7496#section-3.1
|
||||||
|
|
||||||
|
// First, check that the protocol guarantee is preserved.
|
||||||
|
EXPECT_GT(packet_counter,
|
||||||
|
callee()->data_observer()->received_message_count());
|
||||||
|
EXPECT_LE(2u, callee()->data_observer()->received_message_count());
|
||||||
|
// Then, check that observed behavior (lose between 100 and 200 messages)
|
||||||
|
// has not changed.
|
||||||
|
// Usrsctp behavior is different on Android (177) and other platforms (122).
|
||||||
|
// Dcsctp loses 432 packets.
|
||||||
|
EXPECT_GT(2 + packet_counter - 100,
|
||||||
|
callee()->data_observer()->received_message_count());
|
||||||
|
EXPECT_LT(2 + packet_counter - 500,
|
||||||
|
callee()->data_observer()->received_message_count());
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
DataChannelIntegrationTest,
|
DataChannelIntegrationTest,
|
||||||
DataChannelIntegrationTest,
|
DataChannelIntegrationTest,
|
||||||
|
@ -139,6 +139,7 @@ RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
|
|||||||
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
||||||
return RtpCapabilities();
|
return RtpCapabilities();
|
||||||
}
|
}
|
||||||
|
RTC_DLOG(LS_ERROR) << "Got unexpected MediaType " << kind;
|
||||||
RTC_CHECK_NOTREACHED();
|
RTC_CHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +166,7 @@ RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
|
|||||||
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
||||||
return RtpCapabilities();
|
return RtpCapabilities();
|
||||||
}
|
}
|
||||||
|
RTC_DLOG(LS_ERROR) << "Got unexpected MediaType " << kind;
|
||||||
RTC_CHECK_NOTREACHED();
|
RTC_CHECK_NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user