From 84ffdee879c9d13f50288dbf6a2a050b0da95170 Mon Sep 17 00:00:00 2001 From: hbos Date: Wed, 12 Oct 2016 14:14:39 -0700 Subject: [PATCH] DataChannel[Interface]::[message/bytes]_[sent/received]() added. These are required for the RTCDataChannelStats[1] that will be collected in a follow-up CL. [1] https://w3c.github.io/webrtc-stats/#dcstats-dict* BUG=chromium:654927, chromium:627816 Review-Url: https://codereview.webrtc.org/2413803002 Cr-Commit-Position: refs/heads/master@{#14616} --- webrtc/api/datachannel.cc | 12 +++- webrtc/api/datachannel.h | 12 ++++ webrtc/api/datachannel_unittest.cc | 94 ++++++++++++++++++++++++++++++ webrtc/api/datachannelinterface.h | 4 ++ 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/webrtc/api/datachannel.cc b/webrtc/api/datachannel.cc index 066e60c2ee..af694b7b1c 100644 --- a/webrtc/api/datachannel.cc +++ b/webrtc/api/datachannel.cc @@ -126,8 +126,12 @@ DataChannel::DataChannel( cricket::DataChannelType dct, const std::string& label) : label_(label), - observer_(NULL), + observer_(nullptr), state_(kConnecting), + messages_sent_(0), + bytes_sent_(0), + messages_received_(0), + bytes_received_(0), data_channel_type_(dct), provider_(provider), handshake_state_(kHandshakeInit), @@ -367,6 +371,8 @@ void DataChannel::OnDataReceived(cricket::DataChannel* channel, bool binary = (params.type == cricket::DMT_BINARY); std::unique_ptr buffer(new DataBuffer(payload, binary)); if (state_ == kOpen && observer_) { + ++messages_received_; + bytes_received_ += buffer->size(); observer_->OnMessage(*buffer.get()); } else { if (queued_received_data_.byte_count() + payload.size() > @@ -498,6 +504,8 @@ void DataChannel::DeliverQueuedReceivedData() { while (!queued_received_data_.Empty()) { std::unique_ptr buffer(queued_received_data_.Front()); + ++messages_received_; + bytes_received_ += buffer->size(); observer_->OnMessage(*buffer); queued_received_data_.Pop(); } @@ -551,6 +559,8 @@ bool DataChannel::SendDataMessage(const DataBuffer& buffer, bool success = provider_->SendData(send_params, buffer.data, &send_result); if (success) { + ++messages_sent_; + bytes_sent_ += buffer.size(); return true; } diff --git a/webrtc/api/datachannel.h b/webrtc/api/datachannel.h index 714e6e397e..7d7f6c75df 100644 --- a/webrtc/api/datachannel.h +++ b/webrtc/api/datachannel.h @@ -130,6 +130,10 @@ class DataChannel : public DataChannelInterface, virtual uint64_t buffered_amount() const; virtual void Close(); virtual DataState state() const { return state_; } + virtual uint32_t messages_sent() const { return messages_sent_; } + virtual uint64_t bytes_sent() const { return bytes_sent_; } + virtual uint32_t messages_received() const { return messages_received_; } + virtual uint64_t bytes_received() const { return bytes_received_; } virtual bool Send(const DataBuffer& buffer); // rtc::MessageHandler override. @@ -245,6 +249,10 @@ class DataChannel : public DataChannelInterface, InternalDataChannelInit config_; DataChannelObserver* observer_; DataState state_; + uint32_t messages_sent_; + uint64_t bytes_sent_; + uint32_t messages_received_; + uint64_t bytes_received_; cricket::DataChannelType data_channel_type_; DataChannelProviderInterface* provider_; HandshakeState handshake_state_; @@ -274,6 +282,10 @@ BEGIN_SIGNALING_PROXY_MAP(DataChannel) PROXY_CONSTMETHOD0(bool, negotiated) PROXY_CONSTMETHOD0(int, id) PROXY_CONSTMETHOD0(DataState, state) + PROXY_CONSTMETHOD0(uint32_t, messages_sent) + PROXY_CONSTMETHOD0(uint64_t, bytes_sent) + PROXY_CONSTMETHOD0(uint32_t, messages_received) + PROXY_CONSTMETHOD0(uint64_t, bytes_received) PROXY_CONSTMETHOD0(uint64_t, buffered_amount) PROXY_METHOD0(void, Close) PROXY_METHOD1(bool, Send, const DataBuffer&) diff --git a/webrtc/api/datachannel_unittest.cc b/webrtc/api/datachannel_unittest.cc index e2a8eed638..773e7523e6 100644 --- a/webrtc/api/datachannel_unittest.cc +++ b/webrtc/api/datachannel_unittest.cc @@ -195,6 +195,53 @@ TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) { EXPECT_EQ(2U, observer_->on_buffered_amount_change_count()); } +// Tests that DataChannel::messages_sent() and DataChannel::bytes_sent() are +// correct, sending data both while unblocked and while blocked. +TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesSent) { + AddObserver(); + SetChannelReady(); + std::vector buffers({ + webrtc::DataBuffer("message 1"), + webrtc::DataBuffer("msg 2"), + webrtc::DataBuffer("message three"), + webrtc::DataBuffer("quadra message"), + webrtc::DataBuffer("fifthmsg"), + webrtc::DataBuffer("message of the beast"), + }); + + // Default values. + EXPECT_EQ(0U, webrtc_data_channel_->messages_sent()); + EXPECT_EQ(0U, webrtc_data_channel_->bytes_sent()); + + // Send three buffers while not blocked. + provider_->set_send_blocked(false); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[0])); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[1])); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[2])); + size_t bytes_sent = buffers[0].size() + buffers[1].size() + buffers[2].size(); + EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout); + EXPECT_EQ(3U, webrtc_data_channel_->messages_sent()); + EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); + + // Send three buffers while blocked, queuing the buffers. + provider_->set_send_blocked(true); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[3])); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[4])); + EXPECT_TRUE(webrtc_data_channel_->Send(buffers[5])); + size_t bytes_queued = + buffers[3].size() + buffers[4].size() + buffers[5].size(); + EXPECT_EQ(bytes_queued, webrtc_data_channel_->buffered_amount()); + EXPECT_EQ(3U, webrtc_data_channel_->messages_sent()); + EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); + + // Unblock and make sure everything was sent. + provider_->set_send_blocked(false); + EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout); + bytes_sent += bytes_queued; + EXPECT_EQ(6U, webrtc_data_channel_->messages_sent()); + EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); +} + // Tests that the queued control message is sent when channel is ready. TEST_F(SctpDataChannelTest, OpenMessageSent) { // Initially the id is unassigned. @@ -374,6 +421,53 @@ TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) { EXPECT_EQ(0U, provider_->last_send_data_params().ssrc); } +// Tests that DataChannel::messages_received() and DataChannel::bytes_received() +// are correct, receiving data both while not open and while open. +TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesReceived) { + AddObserver(); + std::vector buffers({ + webrtc::DataBuffer("message 1"), + webrtc::DataBuffer("msg 2"), + webrtc::DataBuffer("message three"), + webrtc::DataBuffer("quadra message"), + webrtc::DataBuffer("fifthmsg"), + webrtc::DataBuffer("message of the beast"), + }); + + webrtc_data_channel_->SetSctpSid(1); + cricket::ReceiveDataParams params; + params.ssrc = 1; + + // Default values. + EXPECT_EQ(0U, webrtc_data_channel_->messages_received()); + EXPECT_EQ(0U, webrtc_data_channel_->bytes_received()); + + // Receive three buffers while data channel isn't open. + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[0].data); + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[1].data); + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[2].data); + EXPECT_EQ(0U, observer_->messages_received()); + EXPECT_EQ(0U, webrtc_data_channel_->messages_received()); + EXPECT_EQ(0U, webrtc_data_channel_->bytes_received()); + + // Open channel and make sure everything was received. + SetChannelReady(); + size_t bytes_received = + buffers[0].size() + buffers[1].size() + buffers[2].size(); + EXPECT_EQ(3U, observer_->messages_received()); + EXPECT_EQ(3U, webrtc_data_channel_->messages_received()); + EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received()); + + // Receive three buffers while open. + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[3].data); + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[4].data); + webrtc_data_channel_->OnDataReceived(nullptr, params, buffers[5].data); + bytes_received += buffers[3].size() + buffers[4].size() + buffers[5].size(); + EXPECT_EQ(6U, observer_->messages_received()); + EXPECT_EQ(6U, webrtc_data_channel_->messages_received()); + EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received()); +} + // Tests that OPEN_ACK message is sent if the datachannel is created from an // OPEN message. TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) { diff --git a/webrtc/api/datachannelinterface.h b/webrtc/api/datachannelinterface.h index 53c11d4291..8b788c0468 100644 --- a/webrtc/api/datachannelinterface.h +++ b/webrtc/api/datachannelinterface.h @@ -125,6 +125,10 @@ class DataChannelInterface : public rtc::RefCountInterface { virtual int id() const = 0; virtual DataState state() const = 0; + virtual uint32_t messages_sent() const = 0; + virtual uint64_t bytes_sent() const = 0; + virtual uint32_t messages_received() const = 0; + virtual uint64_t bytes_received() const = 0; // The buffered_amount returns the number of bytes of application data // (UTF-8 text and binary data) that have been queued using SendBuffer but // have not yet been transmitted to the network.