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