Adding test for unordered, fragmented SCTP message delivery.
This functionality broke after a recent usrsctp roll. This test would be useful in catching issues that arise in the future. BUG=633959 R=honghaiz@webrtc.org, pthatcher@webrtc.org Review URL: https://codereview.webrtc.org/2233033002 . Cr-Commit-Position: refs/heads/master@{#13823}
This commit is contained in:
parent
b5b30908dc
commit
9b5306c4ef
@ -31,6 +31,7 @@
|
||||
#include "webrtc/api/test/fakevideotrackrenderer.h"
|
||||
#include "webrtc/api/test/mockpeerconnectionobservers.h"
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/helpers.h"
|
||||
#include "webrtc/base/physicalsocketserver.h"
|
||||
#include "webrtc/base/ssladapter.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
@ -1337,6 +1338,8 @@ class P2PTestConductor : public testing::Test {
|
||||
}
|
||||
}
|
||||
|
||||
rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
|
||||
|
||||
PeerConnectionTestClient* initializing_client() {
|
||||
return initiating_client_.get();
|
||||
}
|
||||
@ -1929,6 +1932,66 @@ TEST_F(P2PTestConductor, LocalP2PTestSctpDataChannel) {
|
||||
EXPECT_TRUE_WAIT(!receiving_client()->data_observer()->IsOpen(), kMaxWaitMs);
|
||||
}
|
||||
|
||||
TEST_F(P2PTestConductor, UnorderedSctpDataChannel) {
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
webrtc::DataChannelInit init;
|
||||
init.ordered = false;
|
||||
initializing_client()->CreateDataChannel(&init);
|
||||
|
||||
// Introduce random network delays.
|
||||
// Otherwise it's not a true "unordered" test.
|
||||
virtual_socket_server()->set_delay_mean(20);
|
||||
virtual_socket_server()->set_delay_stddev(5);
|
||||
virtual_socket_server()->UpdateDelayDistribution();
|
||||
|
||||
initializing_client()->Negotiate();
|
||||
ASSERT_TRUE(initializing_client()->data_channel() != nullptr);
|
||||
EXPECT_TRUE_WAIT(receiving_client()->data_channel() != nullptr, kMaxWaitMs);
|
||||
EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(),
|
||||
kMaxWaitMs);
|
||||
EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), kMaxWaitMs);
|
||||
|
||||
static constexpr int kNumMessages = 100;
|
||||
// Deliberately chosen to be larger than the MTU so messages get fragmented.
|
||||
static constexpr size_t kMaxMessageSize = 4096;
|
||||
// Create and send random messages.
|
||||
std::vector<std::string> sent_messages;
|
||||
for (int i = 0; i < kNumMessages; ++i) {
|
||||
size_t length = (rand() % kMaxMessageSize) + 1;
|
||||
std::string message;
|
||||
ASSERT_TRUE(rtc::CreateRandomString(length, &message));
|
||||
initializing_client()->data_channel()->Send(DataBuffer(message));
|
||||
receiving_client()->data_channel()->Send(DataBuffer(message));
|
||||
sent_messages.push_back(message);
|
||||
}
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
kNumMessages,
|
||||
initializing_client()->data_observer()->received_message_count(),
|
||||
kMaxWaitMs);
|
||||
EXPECT_EQ_WAIT(kNumMessages,
|
||||
receiving_client()->data_observer()->received_message_count(),
|
||||
kMaxWaitMs);
|
||||
|
||||
// Sort and compare to make sure none of the messages were corrupted.
|
||||
std::vector<std::string> initializing_client_received_messages =
|
||||
initializing_client()->data_observer()->messages();
|
||||
std::vector<std::string> receiving_client_received_messages =
|
||||
receiving_client()->data_observer()->messages();
|
||||
std::sort(sent_messages.begin(), sent_messages.end());
|
||||
std::sort(initializing_client_received_messages.begin(),
|
||||
initializing_client_received_messages.end());
|
||||
std::sort(receiving_client_received_messages.begin(),
|
||||
receiving_client_received_messages.end());
|
||||
EXPECT_EQ(sent_messages, initializing_client_received_messages);
|
||||
EXPECT_EQ(sent_messages, receiving_client_received_messages);
|
||||
|
||||
receiving_client()->data_channel()->Close();
|
||||
EXPECT_TRUE_WAIT(!initializing_client()->data_observer()->IsOpen(),
|
||||
kMaxWaitMs);
|
||||
EXPECT_TRUE_WAIT(!receiving_client()->data_observer()->IsOpen(), kMaxWaitMs);
|
||||
}
|
||||
|
||||
// This test sets up a call between two parties and creates a data channel.
|
||||
// The test tests that received data is buffered unless an observer has been
|
||||
// registered.
|
||||
|
||||
@ -74,7 +74,7 @@ class MockSetSessionDescriptionObserver
|
||||
class MockDataChannelObserver : public webrtc::DataChannelObserver {
|
||||
public:
|
||||
explicit MockDataChannelObserver(webrtc::DataChannelInterface* channel)
|
||||
: channel_(channel), received_message_count_(0) {
|
||||
: channel_(channel) {
|
||||
channel_->RegisterObserver(this);
|
||||
state_ = channel_->state();
|
||||
}
|
||||
@ -86,19 +86,21 @@ class MockDataChannelObserver : public webrtc::DataChannelObserver {
|
||||
|
||||
void OnStateChange() override { state_ = channel_->state(); }
|
||||
void OnMessage(const DataBuffer& buffer) override {
|
||||
last_message_.assign(buffer.data.data<char>(), buffer.data.size());
|
||||
++received_message_count_;
|
||||
messages_.push_back(
|
||||
std::string(buffer.data.data<char>(), buffer.data.size()));
|
||||
}
|
||||
|
||||
bool IsOpen() const { return state_ == DataChannelInterface::kOpen; }
|
||||
const std::string& last_message() const { return last_message_; }
|
||||
size_t received_message_count() const { return received_message_count_; }
|
||||
std::vector<std::string> messages() const { return messages_; }
|
||||
std::string last_message() const {
|
||||
return messages_.empty() ? std::string() : messages_.back();
|
||||
}
|
||||
size_t received_message_count() const { return messages_.size(); }
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> channel_;
|
||||
DataChannelInterface::DataState state_;
|
||||
std::string last_message_;
|
||||
size_t received_message_count_;
|
||||
std::vector<std::string> messages_;
|
||||
};
|
||||
|
||||
class MockStatsObserver : public webrtc::StatsObserver {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user