Index: webrtc/modules/rtp_rtcp/source/report_block_information_unittest.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/report_block_information_unittest.cc b/webrtc/modules/rtp_rtcp/source/report_block_information_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e4243c86227bc514f65004e49e6b2b0ef4368769 |
--- /dev/null |
+++ b/webrtc/modules/rtp_rtcp/source/report_block_information_unittest.cc |
@@ -0,0 +1,180 @@ |
+/* |
+ * Copyright (c) 2016 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 <algorithm> |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "webrtc/base/logging.h" |
+#include "webrtc/base/random.h" |
+#include "webrtc/modules/rtp_rtcp/source/report_block_information.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
+#include "webrtc/modules/rtp_rtcp/source/time_util.h" |
+ |
+using webrtc::rtcp::ReportBlock; |
+using webrtc::rtcp::ReportBlockInformation; |
+using webrtc::RTCPUtility::RTCPPacketReportBlockItem; |
+ |
+namespace webrtc { |
+ |
+class RtcpReportBlockInformationTest : public ::testing::Test { |
+ protected: |
+ Random rand_; |
+ const uint32_t kSourceSsrc; |
+ const uint32_t kRemoteSsrc; |
+ const uint32_t kDelayNtp; |
+ const uint8_t kFractionLost; |
+ const uint32_t kCumulativeLost; |
+ const uint32_t kSequenceNumber; |
+ const uint32_t kJitter; |
+ const uint32_t kLastSr; |
+ RtcpReportBlockInformationTest() |
+ : rand_(0x123456789abcdef), |
+ kSourceSsrc(RandSsrc()), |
+ kRemoteSsrc(RandSsrc()), |
+ kDelayNtp(Rand<uint32_t>()), |
+ kFractionLost(Rand<uint8_t>()), |
+ kCumulativeLost(Rand((1 << 24) - 1)), |
+ kSequenceNumber(Rand<uint32_t>()), |
+ kJitter(Rand<uint32_t>()), |
+ kLastSr(Rand<uint32_t>()) {} |
+ |
+ uint32_t RandSsrc() { return rand_.Rand(0x00000001u, 0xfffffffeu); } |
+ template <typename T> |
+ T Rand() { |
+ return rand_.Rand<T>(); |
+ } |
+ uint32_t Rand(uint32_t max) { return rand_.Rand(max); } |
+ uint32_t Rand(uint32_t min, uint32_t max) { return rand_.Rand(min, max); } |
+}; |
+ |
+template <> |
+NtpTime RtcpReportBlockInformationTest::Rand<NtpTime>() { |
+ return NtpTime(Rand<uint32_t>(), Rand<uint32_t>()); |
+} |
+ |
+TEST_F(RtcpReportBlockInformationTest, RemembersLastReportBlock) { |
+ ReportBlockInformation rbi; |
+ const NtpTime kNow = Rand<NtpTime>(); |
+ ReportBlock b; |
+ b.To(kSourceSsrc); |
+ b.WithFractionLost(kFractionLost); |
+ b.WithCumulativeLost(kCumulativeLost); |
+ b.WithExtHighestSeqNum(kSequenceNumber); |
+ b.WithJitter(kJitter); |
+ b.WithLastSr(kLastSr); |
+ b.WithDelayLastSr(kDelayNtp); |
+ |
+ rbi.AddBlock(b, kRemoteSsrc, kNow); |
+ |
+ EXPECT_EQ(kSourceSsrc, rbi.LastBlock().sourceSSRC); |
+ EXPECT_EQ(kRemoteSsrc, rbi.LastBlock().remoteSSRC); |
+ EXPECT_EQ(kFractionLost, rbi.LastBlock().fractionLost); |
+ EXPECT_EQ(kCumulativeLost, rbi.LastBlock().cumulativeLost); |
+ EXPECT_EQ(kSequenceNumber, rbi.LastBlock().extendedHighSeqNum); |
+ EXPECT_EQ(kJitter, rbi.LastBlock().jitter); |
+ EXPECT_EQ(kLastSr, rbi.LastBlock().lastSR); |
+ EXPECT_EQ(kDelayNtp, rbi.LastBlock().delaySinceLastSR); |
+} |
+ |
+TEST_F(RtcpReportBlockInformationTest, AcceptsRTCPUtilityReportBlockItem) { |
+ ReportBlockInformation rbi; |
+ const NtpTime kNow = Rand<NtpTime>(); |
+ RTCPPacketReportBlockItem b; |
+ b.SSRC = kSourceSsrc; |
+ b.FractionLost = kFractionLost; |
+ b.CumulativeNumOfPacketsLost = kCumulativeLost; |
+ b.ExtendedHighestSequenceNumber = kSequenceNumber; |
+ b.Jitter = kJitter; |
+ b.LastSR = kLastSr; |
+ b.DelayLastSR = kDelayNtp; |
+ |
+ rbi.AddBlock(b, kRemoteSsrc, kNow); |
+ |
+ EXPECT_EQ(kSourceSsrc, rbi.LastBlock().sourceSSRC); |
+ EXPECT_EQ(kRemoteSsrc, rbi.LastBlock().remoteSSRC); |
+ EXPECT_EQ(kFractionLost, rbi.LastBlock().fractionLost); |
+ EXPECT_EQ(kCumulativeLost, rbi.LastBlock().cumulativeLost); |
+ EXPECT_EQ(kSequenceNumber, rbi.LastBlock().extendedHighSeqNum); |
+ EXPECT_EQ(kJitter, rbi.LastBlock().jitter); |
+ EXPECT_EQ(kLastSr, rbi.LastBlock().lastSR); |
+ EXPECT_EQ(kDelayNtp, rbi.LastBlock().delaySinceLastSR); |
+} |
+ |
+TEST_F(RtcpReportBlockInformationTest, ReportBlockWithoutRTT) { |
+ ReportBlockInformation rbi; |
+ const NtpTime kNow = Rand<NtpTime>(); |
+ ReportBlock b; |
+ b.To(kSourceSsrc); |
+ b.WithLastSr(0); // LastSR = 0 means RTT can't be calculated. |
+ |
+ rbi.AddBlock(b, kRemoteSsrc, kNow); |
+ |
+ EXPECT_FALSE(rbi.HasRtt()); |
+ EXPECT_EQ(kSourceSsrc, rbi.LastBlock().sourceSSRC); |
+ EXPECT_EQ(kRemoteSsrc, rbi.LastBlock().remoteSSRC); |
+} |
+ |
+TEST_F(RtcpReportBlockInformationTest, ReportBlockWithRTT) { |
+ const uint32_t kRttMs = Rand(1, 18 * 3600 * 1000); |
+ ReportBlockInformation rbi; |
+ SimulatedClock clock(Rand<uint32_t>()); |
+ ReportBlock b; |
+ b.To(kSourceSsrc); |
+ NtpTime start(clock); |
+ b.WithLastSr(CompactNtp(start)); |
+ b.WithDelayLastSr(kDelayNtp); |
+ clock.AdvanceTimeMilliseconds(kRttMs + CompactNtpIntervalToMs(kDelayNtp)); |
+ NtpTime now(clock); |
+ |
+ rbi.AddBlock(b, kRemoteSsrc, now); |
+ |
+ EXPECT_TRUE(rbi.HasRtt()); |
+ EXPECT_NEAR(kRttMs, rbi.LastRttMs(), 1); |
+} |
+ |
+TEST_F(RtcpReportBlockInformationTest, RTTStats) { |
+ const uint32_t kRttMs1 = Rand(1, 18 * 3600 * 1000); |
+ const uint32_t kRttMs2 = Rand(1, 18 * 3600 * 1000); |
+ const uint32_t kRttMs3 = Rand(1, 18 * 3600 * 1000); |
+ const uint32_t kRttMin = std::min({kRttMs1, kRttMs2, kRttMs3}); |
+ const uint32_t kRttMax = std::max({kRttMs1, kRttMs2, kRttMs3}); |
+ const uint32_t kRttAvg = (kRttMs1 + kRttMs2 + kRttMs3) / 3; |
+ const uint32_t kDelayMs = CompactNtpIntervalToMs(kDelayNtp); |
+ ReportBlockInformation rbi; |
+ SimulatedClock clock(Rand<uint32_t>()); |
+ ReportBlock b; |
+ b.To(kSourceSsrc); |
+ const NtpTime start(clock); |
+ b.WithDelayLastSr(kDelayNtp); |
+ |
+ b.WithLastSr(CompactNtp(start)); |
+ clock.AdvanceTimeMilliseconds(kRttMs1 + kDelayMs); |
+ const NtpTime time1(clock); |
+ rbi.AddBlock(b, kRemoteSsrc, time1); |
+ |
+ b.WithLastSr(CompactNtp(time1)); |
+ clock.AdvanceTimeMilliseconds(kRttMs2 + kDelayMs); |
+ const NtpTime time2(clock); |
+ rbi.AddBlock(b, kRemoteSsrc, time2); |
+ |
+ b.WithLastSr(CompactNtp(time2)); |
+ clock.AdvanceTimeMilliseconds(kRttMs3 + kDelayMs); |
+ const NtpTime time3(clock); |
+ rbi.AddBlock(b, kRemoteSsrc, time3); |
+ |
+ EXPECT_TRUE(rbi.HasRtt()); |
+ EXPECT_NEAR(kRttMs3, rbi.LastRttMs(), 1); |
+ EXPECT_NEAR(kRttMin, rbi.MinRttMs(), 1); |
+ EXPECT_NEAR(kRttMax, rbi.MaxRttMs(), 1); |
+ EXPECT_NEAR(kRttAvg, rbi.AvgRttMs(), 1); |
+} |
+ |
+} // namespace webrtc |