1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
12 
13 #include "rtc_base/random.h"
14 #include "test/gmock.h"
15 #include "test/gtest.h"
16 #include "test/rtcp_packet_parser.h"
17 
18 using ::testing::ElementsAre;
19 using ::testing::ElementsAreArray;
20 using ::testing::make_tuple;
21 using ::testing::SizeIs;
22 using webrtc::rtcp::ExtendedReports;
23 using webrtc::rtcp::ReceiveTimeInfo;
24 using webrtc::rtcp::Rrtr;
25 
26 namespace webrtc {
27 // Define comparision operators that shouldn't be needed in production,
28 // but make testing matches more clear.
29 namespace rtcp {
operator ==(const Rrtr & rrtr1,const Rrtr & rrtr2)30 bool operator==(const Rrtr& rrtr1, const Rrtr& rrtr2) {
31   return rrtr1.ntp() == rrtr2.ntp();
32 }
33 
operator ==(const ReceiveTimeInfo & time1,const ReceiveTimeInfo & time2)34 bool operator==(const ReceiveTimeInfo& time1, const ReceiveTimeInfo& time2) {
35   return time1.ssrc == time2.ssrc && time1.last_rr == time2.last_rr &&
36          time1.delay_since_last_rr == time2.delay_since_last_rr;
37 }
38 }  // namespace rtcp
39 
40 namespace {
41 constexpr uint32_t kSenderSsrc = 0x12345678;
42 constexpr uint8_t kEmptyPacket[] = {0x80, 207,  0x00, 0x01,
43                                     0x12, 0x34, 0x56, 0x78};
44 }  // namespace
45 
46 class RtcpPacketExtendedReportsTest : public ::testing::Test {
47  public:
RtcpPacketExtendedReportsTest()48   RtcpPacketExtendedReportsTest() : random_(0x123456789) {}
49 
50  protected:
51   template <typename T>
Rand()52   T Rand() {
53     return random_.Rand<T>();
54   }
55 
56  private:
57   Random random_;
58 };
59 
60 template <>
Rand()61 ReceiveTimeInfo RtcpPacketExtendedReportsTest::Rand<ReceiveTimeInfo>() {
62   uint32_t ssrc = Rand<uint32_t>();
63   uint32_t last_rr = Rand<uint32_t>();
64   uint32_t delay_since_last_rr = Rand<uint32_t>();
65   return ReceiveTimeInfo(ssrc, last_rr, delay_since_last_rr);
66 }
67 
68 template <>
Rand()69 NtpTime RtcpPacketExtendedReportsTest::Rand<NtpTime>() {
70   uint32_t secs = Rand<uint32_t>();
71   uint32_t frac = Rand<uint32_t>();
72   return NtpTime(secs, frac);
73 }
74 
75 template <>
Rand()76 Rrtr RtcpPacketExtendedReportsTest::Rand<Rrtr>() {
77   Rrtr rrtr;
78   rrtr.SetNtp(Rand<NtpTime>());
79   return rrtr;
80 }
81 
TEST_F(RtcpPacketExtendedReportsTest,CreateWithoutReportBlocks)82 TEST_F(RtcpPacketExtendedReportsTest, CreateWithoutReportBlocks) {
83   ExtendedReports xr;
84   xr.SetSenderSsrc(kSenderSsrc);
85 
86   rtc::Buffer packet = xr.Build();
87 
88   EXPECT_THAT(make_tuple(packet.data(), packet.size()),
89               ElementsAreArray(kEmptyPacket));
90 }
91 
TEST_F(RtcpPacketExtendedReportsTest,ParseWithoutReportBlocks)92 TEST_F(RtcpPacketExtendedReportsTest, ParseWithoutReportBlocks) {
93   ExtendedReports parsed;
94   EXPECT_TRUE(test::ParseSinglePacket(kEmptyPacket, &parsed));
95   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
96   EXPECT_FALSE(parsed.rrtr());
97   EXPECT_FALSE(parsed.dlrr());
98 }
99 
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithRrtrBlock)100 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithRrtrBlock) {
101   const Rrtr kRrtr = Rand<Rrtr>();
102   ExtendedReports xr;
103   xr.SetSenderSsrc(kSenderSsrc);
104   xr.SetRrtr(kRrtr);
105   rtc::Buffer packet = xr.Build();
106 
107   ExtendedReports mparsed;
108   EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
109   const ExtendedReports& parsed = mparsed;
110 
111   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
112   EXPECT_EQ(kRrtr, parsed.rrtr());
113 }
114 
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithDlrrWithOneSubBlock)115 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithDlrrWithOneSubBlock) {
116   const ReceiveTimeInfo kTimeInfo = Rand<ReceiveTimeInfo>();
117   ExtendedReports xr;
118   xr.SetSenderSsrc(kSenderSsrc);
119   xr.AddDlrrItem(kTimeInfo);
120 
121   rtc::Buffer packet = xr.Build();
122 
123   ExtendedReports mparsed;
124   EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
125   const ExtendedReports& parsed = mparsed;
126 
127   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
128   EXPECT_THAT(parsed.dlrr().sub_blocks(), ElementsAre(kTimeInfo));
129 }
130 
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithDlrrWithTwoSubBlocks)131 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithDlrrWithTwoSubBlocks) {
132   const ReceiveTimeInfo kTimeInfo1 = Rand<ReceiveTimeInfo>();
133   const ReceiveTimeInfo kTimeInfo2 = Rand<ReceiveTimeInfo>();
134   ExtendedReports xr;
135   xr.SetSenderSsrc(kSenderSsrc);
136   xr.AddDlrrItem(kTimeInfo1);
137   xr.AddDlrrItem(kTimeInfo2);
138 
139   rtc::Buffer packet = xr.Build();
140 
141   ExtendedReports mparsed;
142   EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
143   const ExtendedReports& parsed = mparsed;
144 
145   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
146   EXPECT_THAT(parsed.dlrr().sub_blocks(), ElementsAre(kTimeInfo1, kTimeInfo2));
147 }
148 
TEST_F(RtcpPacketExtendedReportsTest,CreateLimitsTheNumberOfDlrrSubBlocks)149 TEST_F(RtcpPacketExtendedReportsTest, CreateLimitsTheNumberOfDlrrSubBlocks) {
150   const ReceiveTimeInfo kTimeInfo = Rand<ReceiveTimeInfo>();
151   ExtendedReports xr;
152 
153   for (size_t i = 0; i < ExtendedReports::kMaxNumberOfDlrrItems; ++i)
154     EXPECT_TRUE(xr.AddDlrrItem(kTimeInfo));
155   EXPECT_FALSE(xr.AddDlrrItem(kTimeInfo));
156 
157   EXPECT_THAT(xr.dlrr().sub_blocks(),
158               SizeIs(ExtendedReports::kMaxNumberOfDlrrItems));
159 }
160 
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithMaximumReportBlocks)161 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithMaximumReportBlocks) {
162   const Rrtr kRrtr = Rand<Rrtr>();
163 
164   ExtendedReports xr;
165   xr.SetSenderSsrc(kSenderSsrc);
166   xr.SetRrtr(kRrtr);
167   for (size_t i = 0; i < ExtendedReports::kMaxNumberOfDlrrItems; ++i)
168     xr.AddDlrrItem(Rand<ReceiveTimeInfo>());
169 
170   rtc::Buffer packet = xr.Build();
171 
172   ExtendedReports mparsed;
173   EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
174   const ExtendedReports& parsed = mparsed;
175 
176   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
177   EXPECT_EQ(kRrtr, parsed.rrtr());
178   EXPECT_THAT(parsed.dlrr().sub_blocks(),
179               ElementsAreArray(xr.dlrr().sub_blocks()));
180 }
181 
182 }  // namespace webrtc
183