Regression test for SCTP transport.
Tests the behavior of the usrsctp library buffering a large message in unordered mode. The expected behavior is that this message will be sent when the socket becomes unblocked, but instead an SCTP_SEND_FAILED_EVENT is fired by usrsctp library and the message is never sent. This test will pass with a newer version of usrsctp lib, or if the send is in ordered mode. Bug: webrtc:10939 Change-Id: I3b4b05e7dcc7574bf3397991848a9ad7122adc0b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172480 Commit-Queue: Taylor <deadbeef@webrtc.org> Reviewed-by: Seth Hampson <shampson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30950}
This commit is contained in:
parent
0920d5d344
commit
8cdd2c7d3c
@ -365,43 +365,15 @@ TEST_F(SctpTransportTest, SignalReadyToSendDataAfterDtlsWritable) {
|
||||
EXPECT_TRUE_WAIT(observer.ReadyToSend(), kDefaultTimeout);
|
||||
}
|
||||
|
||||
// Test that after an SCTP socket's buffer is filled, SignalReadyToSendData
|
||||
// is fired after it begins to be drained.
|
||||
TEST_F(SctpTransportTest, SignalReadyToSendDataAfterBlocked) {
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
// Wait for initial SCTP association to be formed.
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
// Make the fake transport unwritable so that messages pile up for the SCTP
|
||||
// socket.
|
||||
fake_dtls1()->SetWritable(false);
|
||||
// Send messages until we get EWOULDBLOCK.
|
||||
static const size_t kMaxMessages = 1024;
|
||||
SendDataParams params;
|
||||
params.sid = 1;
|
||||
rtc::CopyOnWriteBuffer buf(1024);
|
||||
memset(buf.data<uint8_t>(), 0, 1024);
|
||||
SendDataResult result;
|
||||
size_t message_count = 0;
|
||||
for (; message_count < kMaxMessages; ++message_count) {
|
||||
if (!transport1()->SendData(params, buf, &result) && result == SDR_BLOCK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(kMaxMessages, message_count)
|
||||
<< "Sent max number of messages without getting SDR_BLOCK?";
|
||||
// Make sure the ready-to-send count hasn't changed.
|
||||
EXPECT_EQ(1, transport1_ready_to_send_count());
|
||||
// Make the transport writable again and expect a "SignalReadyToSendData" at
|
||||
// some point.
|
||||
fake_dtls1()->SetWritable(true);
|
||||
EXPECT_EQ_WAIT(2, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
EXPECT_EQ_WAIT(message_count, receiver2()->num_messages_received(),
|
||||
kDefaultTimeout);
|
||||
}
|
||||
// Run the below tests using both ordered and unordered mode.
|
||||
class SctpTransportTestWithOrdered
|
||||
: public SctpTransportTest,
|
||||
public ::testing::WithParamInterface<bool> {};
|
||||
|
||||
// Tests that a small message gets buffered and later sent by the SctpTransport
|
||||
// when the sctp library only accepts the message partially.
|
||||
TEST_F(SctpTransportTest, SendSmallBufferedOutgoingMessage) {
|
||||
TEST_P(SctpTransportTestWithOrdered, SendSmallBufferedOutgoingMessage) {
|
||||
bool ordered = GetParam();
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
// Wait for initial SCTP association to be formed.
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
@ -409,10 +381,6 @@ TEST_F(SctpTransportTest, SendSmallBufferedOutgoingMessage) {
|
||||
// socket.
|
||||
fake_dtls1()->SetWritable(false);
|
||||
SendDataResult result;
|
||||
// TODO(bugs.webrtc.org/10939): We can't test this behavior unless we are
|
||||
// sending in ordered mode becuase the sctp lib drops large buffered data in
|
||||
// unordered mode.
|
||||
bool ordered = true;
|
||||
|
||||
// Fill almost all of sctp library's send buffer.
|
||||
ASSERT_TRUE(SendData(transport1(), /*sid=*/1,
|
||||
@ -444,7 +412,8 @@ TEST_F(SctpTransportTest, SendSmallBufferedOutgoingMessage) {
|
||||
|
||||
// Tests that a large message gets buffered and later sent by the SctpTransport
|
||||
// when the sctp library only accepts the message partially.
|
||||
TEST_F(SctpTransportTest, SendLargeBufferedOutgoingMessage) {
|
||||
TEST_P(SctpTransportTestWithOrdered, SendLargeBufferedOutgoingMessage) {
|
||||
bool ordered = GetParam();
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
// Wait for initial SCTP association to be formed.
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
@ -452,10 +421,6 @@ TEST_F(SctpTransportTest, SendLargeBufferedOutgoingMessage) {
|
||||
// socket.
|
||||
fake_dtls1()->SetWritable(false);
|
||||
SendDataResult result;
|
||||
// TODO(bugs.webrtc.org/10939): We can't test this behavior unless we are
|
||||
// sending in ordered mode becuase the sctp lib drops large buffered data in
|
||||
// unordered mode.
|
||||
bool ordered = true;
|
||||
|
||||
// Fill almost all of sctp library's send buffer.
|
||||
ASSERT_TRUE(SendData(transport1(), /*sid=*/1,
|
||||
@ -485,13 +450,14 @@ TEST_F(SctpTransportTest, SendLargeBufferedOutgoingMessage) {
|
||||
EXPECT_EQ(2u, receiver2()->num_messages_received());
|
||||
}
|
||||
|
||||
TEST_F(SctpTransportTest, SendData) {
|
||||
TEST_P(SctpTransportTestWithOrdered, SendData) {
|
||||
bool ordered = GetParam();
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
|
||||
SendDataResult result;
|
||||
RTC_LOG(LS_VERBOSE)
|
||||
<< "transport1 sending: 'hello?' -----------------------------";
|
||||
ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
|
||||
ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result, ordered));
|
||||
EXPECT_EQ(SDR_SUCCESS, result);
|
||||
EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
|
||||
RTC_LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received()
|
||||
@ -505,7 +471,7 @@ TEST_F(SctpTransportTest, SendData) {
|
||||
|
||||
RTC_LOG(LS_VERBOSE)
|
||||
<< "transport2 sending: 'hi transport1' -----------------------------";
|
||||
ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
|
||||
ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result, ordered));
|
||||
EXPECT_EQ(SDR_SUCCESS, result);
|
||||
EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
|
||||
kDefaultTimeout);
|
||||
@ -520,12 +486,13 @@ TEST_F(SctpTransportTest, SendData) {
|
||||
}
|
||||
|
||||
// Sends a lot of large messages at once and verifies SDR_BLOCK is returned.
|
||||
TEST_F(SctpTransportTest, SendDataBlocked) {
|
||||
TEST_P(SctpTransportTestWithOrdered, SendDataBlocked) {
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
|
||||
SendDataResult result;
|
||||
SendDataParams params;
|
||||
params.sid = 1;
|
||||
params.ordered = GetParam();
|
||||
|
||||
std::vector<char> buffer(1024 * 64, 0);
|
||||
|
||||
@ -539,6 +506,65 @@ TEST_F(SctpTransportTest, SendDataBlocked) {
|
||||
EXPECT_EQ(SDR_BLOCK, result);
|
||||
}
|
||||
|
||||
// Test that after an SCTP socket's buffer is filled, SignalReadyToSendData
|
||||
// is fired after it begins to be drained.
|
||||
TEST_P(SctpTransportTestWithOrdered, SignalReadyToSendDataAfterBlocked) {
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
// Wait for initial SCTP association to be formed.
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
// Make the fake transport unwritable so that messages pile up for the SCTP
|
||||
// socket.
|
||||
fake_dtls1()->SetWritable(false);
|
||||
// Send messages until we get EWOULDBLOCK.
|
||||
static const size_t kMaxMessages = 1024;
|
||||
SendDataParams params;
|
||||
params.sid = 1;
|
||||
params.ordered = GetParam();
|
||||
rtc::CopyOnWriteBuffer buf(1024);
|
||||
memset(buf.data<uint8_t>(), 0, 1024);
|
||||
SendDataResult result;
|
||||
size_t message_count = 0;
|
||||
for (; message_count < kMaxMessages; ++message_count) {
|
||||
if (!transport1()->SendData(params, buf, &result) && result == SDR_BLOCK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(kMaxMessages, message_count)
|
||||
<< "Sent max number of messages without getting SDR_BLOCK?";
|
||||
// Make sure the ready-to-send count hasn't changed.
|
||||
EXPECT_EQ(1, transport1_ready_to_send_count());
|
||||
// Make the transport writable again and expect a "SignalReadyToSendData" at
|
||||
// some point.
|
||||
fake_dtls1()->SetWritable(true);
|
||||
EXPECT_EQ_WAIT(2, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
EXPECT_EQ_WAIT(message_count, receiver2()->num_messages_received(),
|
||||
kDefaultTimeout);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(SctpTransportTest,
|
||||
SctpTransportTestWithOrdered,
|
||||
::testing::Bool());
|
||||
|
||||
// This is a regression test that fails with earlier versions of SCTP in
|
||||
// unordered mode. See bugs.webrtc.org/10939.
|
||||
TEST_F(SctpTransportTest, SendsLargeDataBufferedBySctpLib) {
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
// Wait for initial SCTP association to be formed.
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
// Make the fake transport unwritable so that messages pile up for the SCTP
|
||||
// socket.
|
||||
fake_dtls1()->SetWritable(false);
|
||||
|
||||
SendDataResult result;
|
||||
std::string buffered_message(kSctpSendBufferSize - 1, 'a');
|
||||
ASSERT_TRUE(SendData(transport1(), 1, buffered_message, &result, false));
|
||||
|
||||
fake_dtls1()->SetWritable(true);
|
||||
EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
|
||||
EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, buffered_message),
|
||||
kDefaultTimeout);
|
||||
}
|
||||
|
||||
// Trying to send data for a nonexistent stream should fail.
|
||||
TEST_F(SctpTransportTest, SendDataWithNonexistentStreamFails) {
|
||||
SetupConnectedTransportsWithTwoStreams();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user