Chromium Code Reviews| 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..78cc5c6fc9ac56614eacdda5fe3f99c5bdb07be7 | 
| --- /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(rbi.LastBlock().sourceSSRC, kSourceSsrc); | 
| 
 
philipel
2016/02/29 13:21:48
Switch to expected value first:
EXPECT_EQ(kSourceS
 
danilchap
2016/02/29 14:41:27
Done.
 
 | 
| + EXPECT_EQ(rbi.LastBlock().remoteSSRC, kRemoteSsrc); | 
| + EXPECT_EQ(rbi.LastBlock().fractionLost, kFractionLost); | 
| + EXPECT_EQ(rbi.LastBlock().cumulativeLost, kCumulativeLost); | 
| + EXPECT_EQ(rbi.LastBlock().extendedHighSeqNum, kSequenceNumber); | 
| + EXPECT_EQ(rbi.LastBlock().jitter, kJitter); | 
| + EXPECT_EQ(rbi.LastBlock().lastSR, kLastSr); | 
| + EXPECT_EQ(rbi.LastBlock().delaySinceLastSR, kDelayNtp); | 
| +} | 
| + | 
| +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(rbi.LastBlock().sourceSSRC, kSourceSsrc); | 
| 
 
philipel
2016/02/29 13:21:48
switch
 
danilchap
2016/02/29 14:41:27
Done.
 
 | 
| + EXPECT_EQ(rbi.LastBlock().remoteSSRC, kRemoteSsrc); | 
| + EXPECT_EQ(rbi.LastBlock().fractionLost, kFractionLost); | 
| + EXPECT_EQ(rbi.LastBlock().cumulativeLost, kCumulativeLost); | 
| + EXPECT_EQ(rbi.LastBlock().extendedHighSeqNum, kSequenceNumber); | 
| + EXPECT_EQ(rbi.LastBlock().jitter, kJitter); | 
| + EXPECT_EQ(rbi.LastBlock().lastSR, kLastSr); | 
| + EXPECT_EQ(rbi.LastBlock().delaySinceLastSR, kDelayNtp); | 
| +} | 
| + | 
| +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(rbi.LastBlock().sourceSSRC, kSourceSsrc); | 
| 
 
philipel
2016/02/29 13:21:48
switch
 
danilchap
2016/02/29 14:41:28
Done.
 
 | 
| + EXPECT_EQ(rbi.LastBlock().remoteSSRC, kRemoteSsrc); | 
| +} | 
| + | 
| +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>()); | 
| 
 
philipel
2016/02/29 13:21:48
Why do you use Random values? If you seed the rand
 
danilchap
2016/02/29 14:41:27
Random values demonstrate the range of values this
 
 | 
| + 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 |