Files
platform-external-webrtc/webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
Henrik Kjellander ff761fba82 modules: more interface -> include renames
This changes the following module directories:
* webrtc/modules/audio_conference_mixer/interface
* webrtc/modules/interface
* webrtc/modules/media_file/interface
* webrtc/modules/rtp_rtcp/interface
* webrtc/modules/utility/interface

To avoid breaking downstream, I followed this recipe:
1. Copy the interface dir to a new sibling directory: include
2. Update the header guards in the include directory to match the style guide.
3. Update the header guards in the interface directory to match the ones in include. This is required to avoid getting redefinitions in the not-yet-updated downstream code.
4. Add a pragma warning in the header files in the interface dir. Example:
#pragma message("WARNING: webrtc/modules/interface is DEPRECATED; "
                "use webrtc/modules/include")
5. Search for all source references to webrtc/modules/interface and update them to webrtc/modules/include (*.c*,*.h,*.mm,*.S)
6. Update all GYP+GN files. This required manual inspection since many subdirectories of webrtc/modules referenced the interface dir using ../interface etc(*.gyp*,*.gn*)

BUG=5095
TESTED=Passing compile-trybots with --clobber flag:
git cl try --clobber --bot=win_compile_rel --bot=linux_compile_rel --bot=android_compile_rel --bot=mac_compile_rel --bot=ios_rel -m tryserver.webrtc

R=stefan@webrtc.org, tommi@webrtc.org

Review URL: https://codereview.webrtc.org/1417683006 .

Cr-Commit-Position: refs/heads/master@{#10500}
2015-11-04 07:32:04 +00:00

382 lines
14 KiB
C++

/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
const size_t kPacketSize1 = 100;
const size_t kPacketSize2 = 300;
const uint32_t kSsrc1 = 1;
const uint32_t kSsrc2 = 2;
class ReceiveStatisticsTest : public ::testing::Test {
public:
ReceiveStatisticsTest() :
clock_(0),
receive_statistics_(ReceiveStatistics::Create(&clock_)) {
memset(&header1_, 0, sizeof(header1_));
header1_.ssrc = kSsrc1;
header1_.sequenceNumber = 100;
memset(&header2_, 0, sizeof(header2_));
header2_.ssrc = kSsrc2;
header2_.sequenceNumber = 100;
}
protected:
SimulatedClock clock_;
rtc::scoped_ptr<ReceiveStatistics> receive_statistics_;
RTPHeader header1_;
RTPHeader header2_;
};
TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(100);
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1);
ASSERT_TRUE(statistician != NULL);
EXPECT_GT(statistician->BitrateReceived(), 0u);
size_t bytes_received = 0;
uint32_t packets_received = 0;
statistician->GetDataCounters(&bytes_received, &packets_received);
EXPECT_EQ(200u, bytes_received);
EXPECT_EQ(2u, packets_received);
statistician =
receive_statistics_->GetStatistician(kSsrc2);
ASSERT_TRUE(statistician != NULL);
EXPECT_GT(statistician->BitrateReceived(), 0u);
statistician->GetDataCounters(&bytes_received, &packets_received);
EXPECT_EQ(600u, bytes_received);
EXPECT_EQ(2u, packets_received);
StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
EXPECT_EQ(2u, statisticians.size());
// Add more incoming packets and verify that they are registered in both
// access methods.
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
statisticians[kSsrc1]->GetDataCounters(&bytes_received, &packets_received);
EXPECT_EQ(300u, bytes_received);
EXPECT_EQ(3u, packets_received);
statisticians[kSsrc2]->GetDataCounters(&bytes_received, &packets_received);
EXPECT_EQ(900u, bytes_received);
EXPECT_EQ(3u, packets_received);
receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
&bytes_received, &packets_received);
EXPECT_EQ(300u, bytes_received);
EXPECT_EQ(3u, packets_received);
receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
&bytes_received, &packets_received);
EXPECT_EQ(900u, bytes_received);
EXPECT_EQ(3u, packets_received);
}
TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(1000);
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
// Nothing should time out since only 1000 ms has passed since the first
// packet came in.
EXPECT_EQ(2u, statisticians.size());
clock_.AdvanceTimeMilliseconds(7000);
// kSsrc1 should have timed out.
statisticians = receive_statistics_->GetActiveStatisticians();
EXPECT_EQ(1u, statisticians.size());
clock_.AdvanceTimeMilliseconds(1000);
// kSsrc2 should have timed out.
statisticians = receive_statistics_->GetActiveStatisticians();
EXPECT_EQ(0u, statisticians.size());
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
// kSsrc1 should be active again and the data counters should have survived.
statisticians = receive_statistics_->GetActiveStatisticians();
EXPECT_EQ(1u, statisticians.size());
StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1);
ASSERT_TRUE(statistician != NULL);
size_t bytes_received = 0;
uint32_t packets_received = 0;
statistician->GetDataCounters(&bytes_received, &packets_received);
EXPECT_EQ(200u, bytes_received);
EXPECT_EQ(2u, packets_received);
}
TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1);
ASSERT_TRUE(statistician != NULL);
StreamDataCounters counters;
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(1u, counters.transmitted.packets);
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(2u, counters.transmitted.packets);
}
TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
class TestCallback : public RtcpStatisticsCallback {
public:
TestCallback()
: RtcpStatisticsCallback(), num_calls_(0), ssrc_(0), stats_() {}
virtual ~TestCallback() {}
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
uint32_t ssrc) {
ssrc_ = ssrc;
stats_ = statistics;
++num_calls_;
}
void CNameChanged(const char* cname, uint32_t ssrc) override {}
uint32_t num_calls_;
uint32_t ssrc_;
RtcpStatistics stats_;
} callback;
receive_statistics_->RegisterRtcpStatisticsCallback(&callback);
// Add some arbitrary data, with loss and jitter.
header1_.sequenceNumber = 1;
clock_.AdvanceTimeMilliseconds(7);
header1_.timestamp += 3;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
header1_.sequenceNumber += 2;
clock_.AdvanceTimeMilliseconds(9);
header1_.timestamp += 9;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
--header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(13);
header1_.timestamp += 47;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
header1_.sequenceNumber += 3;
clock_.AdvanceTimeMilliseconds(11);
header1_.timestamp += 17;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
EXPECT_EQ(0u, callback.num_calls_);
// Call GetStatistics, simulating a timed rtcp sender thread.
RtcpStatistics statistics;
receive_statistics_->GetStatistician(kSsrc1)
->GetStatistics(&statistics, true);
EXPECT_EQ(1u, callback.num_calls_);
EXPECT_EQ(callback.ssrc_, kSsrc1);
EXPECT_EQ(statistics.cumulative_lost, callback.stats_.cumulative_lost);
EXPECT_EQ(statistics.extended_max_sequence_number,
callback.stats_.extended_max_sequence_number);
EXPECT_EQ(statistics.fraction_lost, callback.stats_.fraction_lost);
EXPECT_EQ(statistics.jitter, callback.stats_.jitter);
EXPECT_EQ(51, statistics.fraction_lost);
EXPECT_EQ(1u, statistics.cumulative_lost);
EXPECT_EQ(5u, statistics.extended_max_sequence_number);
EXPECT_EQ(4u, statistics.jitter);
receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
// Add some more data.
header1_.sequenceNumber = 1;
clock_.AdvanceTimeMilliseconds(7);
header1_.timestamp += 3;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
header1_.sequenceNumber += 2;
clock_.AdvanceTimeMilliseconds(9);
header1_.timestamp += 9;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
--header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(13);
header1_.timestamp += 47;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
header1_.sequenceNumber += 3;
clock_.AdvanceTimeMilliseconds(11);
header1_.timestamp += 17;
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
receive_statistics_->GetStatistician(kSsrc1)
->GetStatistics(&statistics, true);
// Should not have been called after deregister.
EXPECT_EQ(1u, callback.num_calls_);
}
class RtpTestCallback : public StreamDataCountersCallback {
public:
RtpTestCallback()
: StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
virtual ~RtpTestCallback() {}
virtual void DataCountersUpdated(const StreamDataCounters& counters,
uint32_t ssrc) {
ssrc_ = ssrc;
stats_ = counters;
++num_calls_;
}
void MatchPacketCounter(const RtpPacketCounter& expected,
const RtpPacketCounter& actual) {
EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
EXPECT_EQ(expected.header_bytes, actual.header_bytes);
EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
EXPECT_EQ(expected.packets, actual.packets);
}
void Matches(uint32_t num_calls,
uint32_t ssrc,
const StreamDataCounters& expected) {
EXPECT_EQ(num_calls, num_calls_);
EXPECT_EQ(ssrc, ssrc_);
MatchPacketCounter(expected.transmitted, stats_.transmitted);
MatchPacketCounter(expected.retransmitted, stats_.retransmitted);
MatchPacketCounter(expected.fec, stats_.fec);
}
uint32_t num_calls_;
uint32_t ssrc_;
StreamDataCounters stats_;
};
TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
RtpTestCallback callback;
receive_statistics_->RegisterRtpStatisticsCallback(&callback);
const size_t kHeaderLength = 20;
const size_t kPaddingLength = 9;
// One packet of size kPacketSize1.
header1_.headerLength = kHeaderLength;
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
StreamDataCounters expected;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
expected.transmitted.padding_bytes = 0;
expected.transmitted.packets = 1;
expected.retransmitted.payload_bytes = 0;
expected.retransmitted.header_bytes = 0;
expected.retransmitted.padding_bytes = 0;
expected.retransmitted.packets = 0;
expected.fec.packets = 0;
callback.Matches(1, kSsrc1, expected);
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(5);
header1_.paddingLength = 9;
// Another packet of size kPacketSize1 with 9 bytes padding.
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false);
expected.transmitted.payload_bytes = kPacketSize1 * 2;
expected.transmitted.header_bytes = kHeaderLength * 2;
expected.transmitted.padding_bytes = kPaddingLength;
expected.transmitted.packets = 2;
callback.Matches(2, kSsrc1, expected);
clock_.AdvanceTimeMilliseconds(5);
// Retransmit last packet.
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true);
expected.transmitted.payload_bytes = kPacketSize1 * 3;
expected.transmitted.header_bytes = kHeaderLength * 3;
expected.transmitted.padding_bytes = kPaddingLength * 2;
expected.transmitted.packets = 3;
expected.retransmitted.payload_bytes = kPacketSize1;
expected.retransmitted.header_bytes = kHeaderLength;
expected.retransmitted.padding_bytes = kPaddingLength;
expected.retransmitted.packets = 1;
callback.Matches(3, kSsrc1, expected);
header1_.paddingLength = 0;
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(5);
// One FEC packet.
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
receive_statistics_->FecPacketReceived(header1_,
kPacketSize1 + kHeaderLength);
expected.transmitted.payload_bytes = kPacketSize1 * 4;
expected.transmitted.header_bytes = kHeaderLength * 4;
expected.transmitted.packets = 4;
expected.fec.payload_bytes = kPacketSize1;
expected.fec.header_bytes = kHeaderLength;
expected.fec.packets = 1;
callback.Matches(5, kSsrc1, expected);
receive_statistics_->RegisterRtpStatisticsCallback(NULL);
// New stats, but callback should not be called.
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(5);
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, true);
callback.Matches(5, kSsrc1, expected);
}
TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
RtpTestCallback callback;
receive_statistics_->RegisterRtpStatisticsCallback(&callback);
const uint32_t kHeaderLength = 20;
header1_.headerLength = kHeaderLength;
// If first packet is FEC, ignore it.
receive_statistics_->FecPacketReceived(header1_,
kPacketSize1 + kHeaderLength);
EXPECT_EQ(0u, callback.num_calls_);
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
StreamDataCounters expected;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
expected.transmitted.padding_bytes = 0;
expected.transmitted.packets = 1;
expected.fec.packets = 0;
callback.Matches(1, kSsrc1, expected);
receive_statistics_->FecPacketReceived(header1_,
kPacketSize1 + kHeaderLength);
expected.fec.payload_bytes = kPacketSize1;
expected.fec.header_bytes = kHeaderLength;
expected.fec.packets = 1;
callback.Matches(2, kSsrc1, expected);
}
} // namespace webrtc